如何检查变量是否存在?


953

我想检查一个变量是否存在。现在我正在做这样的事情:

try:
   myVar
except NameError:
   # Do something.

是否有其他方法无一例外?


15
异常怎么了?
S.Lott,2009年

10
@ S.Lott:如果myVar真的很复杂,需要花费很长时间来进行生产/评估,那么try慢下来的事情就不会了吗?
dbliss 2015年

3
@dbliss:这是一个变量。除了一些非常奇怪的情况之外,如果您要对疯狂exec或元类做一些疯狂的事情,那也不会太昂贵。
user2357112在2013年

Answers:


1626

要检查是否存在局部变量:

if 'myVar' in locals():
  # myVar exists.

要检查是否存在全局变量:

if 'myVar' in globals():
  # myVar exists.

要检查对象是否具有属性:

if hasattr(obj, 'attr_name'):
  # obj.attr_name exists.

29
好的,如何检查类中存在的属性?
Max Frai

7
以及如何将可能不存在的变量的名称转换为字符串?
SilentGhost

15
但是OP正在键入代码,他们可以代替myVar输入'myVar'。如果在编写代码时不知道变量名,它将在运行时存储在字符串变量中,我发布的检查也将起作用。
艾曼·胡里厄

8
也有内置变量,如果有嵌套函数,则还有外部作用域中的变量。如果要检查所有这些内容,那么最终最好触发NameError
Petr Viktorin 2014年

14
我也喜欢最if hasattr(obj, 'attr_name'):适合班级的作品:即if hasattr(self, 'attr_name'):
罗恩·卡利安

118

使用中那些尚未被定义或组(或明或暗地)变量几乎总是一件坏事任何语言,因为这往往预示着该计划的逻辑还没有被恰当地考虑,并有可能的结果行为无法预测。

如果您需要在Python中执行此操作,以下与您的操作类似的技巧将确保变量在使用前具有一定的价值:

try:
    myVar
except NameError:
    myVar = None

# Now you're free to use myVar without Python complaining.

但是,我仍然不认为这是个好主意-在我看来,您应该尝试重构代码,以免发生这种情况。


8
也许这是一个依赖变量,根据它可能存在或可能不存在的版本/平台,没有其他方法可以知道它是什么版本。
WhyNotHugo'2

35
状态变量在分配之前不存在-如果您从前一个位置到当前位置画一条线,然后设置previous = current,这并不意味着您在第一次调用时就“不知道您的变量”。而且,在绘制例程之外编写额外的代码行来初始化previous = null并不意味着您会“更好地了解变量”。
戴夫

4
我的观点是,“ if last:draw(last,current); last = current”这一块很容易理解,而且编程也不差。在测试之前添加“ try / except”以检查是否存在“ last”,这有损于该代码的可读性。
戴夫

23
“使用未定义的变量实际上在任何语言中都是一件坏事”,请给我谦逊的演讲。我们中的某些人使用Python来实现简单的数学或统计脚本,这些脚本使用的是像Matpy这样的IDE,例如Spyder。在某些环境下,有时允许用户在全局控制台中定义变量,并检查脚本中未声明的变量(例如在Matlab中进行数学运算时)是有意义的。
里卡多·克鲁兹

15
@Ricardo,也许,而不是假设它的优越感,你可能要至少考虑的可能性,这是从别人只是很好的意见谁可能是更有知识:-)或者你会认为这是同样光顾,如果我建议不要使用不受约束的全球变量,意大利面条式代码,上帝对象,发布未经测试的代码或用COBOL编写操作系统?我的回答说明了为什么我认为这是一个坏主意(问题中没有任何内容表明为什么OP认为有必要),但仍然提供了他们真正想这样做的机会。
paxdiablo 2015年

52

一种简单的方法是一开始就初始化它 myVar = None

然后稍后:

if myVar is not None:
    # Do something

2
这个答案有很多需要改进的地方。而是-一种简单的方法是先声明它。 myVar = none # do stuff... if not myVar: # give myVar a value myVar = 'something'
肖恩·梅汉

我非常喜欢这个,因为我在except声明
中将其

为什么不这样:if myVar: # Do something 避免了阅读双重否定
词-jjisnow

@jjisnow因为您希望即使myVar一个空列表,零,空字符串等条件都为真,所以也是如此。–
Gabriel

7
如果未声明myVar,则@jjisnow if myVar: # Do something抛出NameErrorpython3
敏捷豆

25

使用try / except是测试变量是否存在的最佳方法。但是几乎可以肯定,有一种比设置/测试全局变量更好的方法。

例如,如果您想在第一次调用某个函数时初始化模块级变量,那么最好使用如下代码:

my_variable = None

def InitMyVariable():
  global my_variable
  if my_variable is None:
    my_variable = ...

2
我尽量不要使用它,因为它会污染全局名称空间。避免这种情况的一种方法是使函数成为一个类,并将my_variable作为类变量,并将call定义为现有函数的主体,但这给编写代码带来了麻烦,并提出了许多其他问题。我更喜欢使用函数属性,请参见下文。
samwyse 2014年

17

对于对象/模块,您还可以

'var' in dir(obj)

例如,

>>> class Something(object):
...     pass
...
>>> c = Something()
>>> c.a = 1
>>> 'a' in dir(c)
True
>>> 'b' in dir(c)
False

11

我将假定该测试将在功能中使用,类似于user97370的答案。我不喜欢这个答案,因为它污染了全局名称空间。解决该问题的一种方法是改用类:

class InitMyVariable(object):
  my_variable = None

def __call__(self):
  if self.my_variable is None:
   self.my_variable = ...

我不喜欢这样,因为它使代码复杂化,并提出了一些问题,例如,是否应该确认Singleton编程模式?幸运的是,Python允许函数在一段时间内拥有属性,这为我们提供了一个简单的解决方案:

def InitMyVariable():
  if InitMyVariable.my_variable is None:
    InitMyVariable.my_variable = ...
InitMyVariable.my_variable = None


5

处理这种情况的一种通常有效的方法是不显式检查变量是否存在,而只是继续将可能不存在的变量的首次用法包装在try / except NameError中:

# Search for entry.
for x in y:
  if x == 3:
    found = x

# Work with found entry.
try:
  print('Found: {0}'.format(found))
except NameError:
  print('Not found')
else:
  # Handle rest of Found case here
  ...

3

我创建了一个自定义函数。

def exists(var):
     var_exists = var in locals() or var in globals()
     return var_exists

然后调用如下函数,将其替换variable_name为要检查的变量:

exists("variable_name")

将返回TrueFalse


2
不,这行不通。locals()是...错误...函数...的局部exists
bgusach

1
1)locals()函数是本地的。2)为什么要额外分配var_exists?
戴夫
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.