如何检查变量是否存在?

时间:2009-05-09 13:10:32

标签: python exception variables

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

try:
   myVar
except NameError:
   # Do something.

还有其他方法没有例外吗?

15 个答案:

答案 0 :(得分:1332)

检查是否存在局部变量:

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

检查是否存在全局变量:

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

检查对象是否具有属性:

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

答案 1 :(得分:101)

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

以下技巧与您的类似,将确保变量在使用前具有某些值:

try:
    myVar
except NameError:
    myVar = None
# Now you're free to use myVar without Python complaining.

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

答案 2 :(得分:31)

一种简单的方法是首先初始化myVar = None

然后是:

if myVar is not None:
    # Do something

答案 3 :(得分:20)

使用try / except是测试变量存在的最佳方法。但是,与设置/测试全局变量相比,几乎肯定有更好的方法来做你正在做的事情。

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

my_variable = None

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

答案 4 :(得分:15)

对象/模块,你也可以

'var' in dir(obj)

例如,

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

答案 5 :(得分:10)

我将假设测试将在函数中使用,类似于user97370's answer。我不喜欢这个答案,因为它会污染全局命名空间。修复它的一种方法是改为使用类:

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

答案 6 :(得分:7)

catch在Python中称为except。除此之外,对于这种简单的案件来说这很好。可以使用AttributeError来检查对象是否具有属性。

答案 7 :(得分: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
  ...

答案 8 :(得分:5)

它只是对先前答案的补充,以检查JSON / Dict中是否存在密钥在python

' Json / Dict对象名称' .has_key('键名')

这将返回True或False

答案 9 :(得分:5)

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

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

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

exists("variable_name")

将返回TrueFalse

答案 10 :(得分:0)

简短变体:

my_var = some_value if 'my_var' not in globals() else my_var:

答案 11 :(得分:0)

这是我的情况:

for i in generate_numbers():
    do_something(i)
# Use the last i.

我无法轻松确定length of the iterable,这意味着i可能存在或不存在,具体取决于迭代器是否产生空序列。

如果我想使用可迭代对象的最后一个i(空序列中不存在的i),我可以做两件事之一:

i = None  # Declare the variable.
for i in generate_numbers():
    do_something(i)
use_last(i)

for i in generate_numbers():
    do_something(i)
try:
    use_last(i)
except UnboundLocalError:
    pass  # i didn’t exist because sequence was empty.

第一个解决方案 可能会出现问题,因为我无法确定i是否是最后一个元素(取决于序列值)。第二种解决方案在这方面更准确。

答案 12 :(得分:0)

像这样:

def no(var):
    "give var as a string (quote it like 'var')"
    assert(var not in vars())
    assert(var not in globals())
    assert(var not in vars(__builtins__))
    import keyword
    assert(var not in keyword.kwlist)

然后:

no('foo')
foo = ....

如果您的新变量 foo 使用不安全,您将收到一个 AssertionError 异常,该异常将指向失败的行,然后您就会知道得更好。 这是明显人为的自我引用:

no('no')

---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-88-d14ecc6b025a> in <module>
----> 1 no('no')

<ipython-input-86-888a9df72be0> in no(var)
      2     "give var as a string (quote it)"
      3     assert( var not in vars())
----> 4     assert( var not in globals())
      5     assert( var not in vars(__builtins__))
      6     import keyword

AssertionError: 

答案 13 :(得分:0)

对于对象,也可以使用 __dict__

class A(object):
    def __init__(self):
        self.m = 1

a = A()
assert "m" in a.__dict__
assert "k" not in a.__dict__

答案 14 :(得分:0)

它可能没有性能,但您可以将解决方案推广到检查局部变量和全局变量的函数。

import inspect
def exists_var(var_name):
    frame = inspect.currentframe()
    try:
        return var_name in frame.f_back.f_locals or var_name in globals()
    finally:
        del frame

然后你可以这样使用它:

exists_var('myVar')