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

try:
    myVar
except NameError:
    # Do something.

有没有其他没有例外的方法?


当前回答

处理这种情况的一种方法通常是不显式检查变量是否存在,而是直接将可能不存在的变量的第一次使用包装在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
  ...

其他回答

处理这种情况的一种方法通常是不显式检查变量是否存在,而是直接将可能不存在的变量的第一次使用包装在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
  ...

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

例如,如果你想在第一次调用某个函数时初始化一个模块级变量,你最好使用这样的代码:

my_variable = None

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

对于对象/模块,也可以

'var' in dir(obj)

例如,

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

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

def exists(var):
     return var in globals()

然后调用函数,将variable_name替换为你想检查的变量:

exists("variable_name")

将返回True或False

在任何语言中,使用尚未定义或设置(隐式或显式)的变量通常都是一件坏事,因为它往往表明程序的逻辑没有经过适当的考虑,并可能导致不可预测的行为。

如果你需要在Python中这样做,下面的技巧,与你的类似,将确保变量在使用前有一些值:

try:
    myVar
except NameError:
    myVar = None      # or some other default value.

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

然而,我仍然不相信这是一个好主意——在我看来,您应该尝试重构您的代码,这样就不会出现这种情况。

作为示例,下面的注释中给出了以下代码,以允许从上一个点绘制到当前点的直线:

if last:
    draw(last, current);
last = current

在last没有绑定值的情况下,这在Python中根本没有帮助,因为即使检查last也会引发异常。更好的办法是确保last确实有一个值,这个值可以用来决定它是否有效。大概是这样的:

last = None

# some time passes ...

if last is not None:
    draw(last, current);
last = current

这确保了变量的存在,并且只在它对需要它的目的有效时才使用它。这就是我假设if last在注释代码中要做的事情(但没有),如果你无法控制变量的初始设置,你仍然可以添加代码来强制执行,使用上面的exception方法:

# Variable 'last' may or may not be bound to a value at this point.

try:
    last
except NameError:
    last = None

# It will always now be bound to a value at this point.

if last is not None:
    draw(last, current);
last = current