如何检查变量是否存在?

Max*_*rai 849 python variables exception

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

try:
   myVar
except NameError:
   # Do something.
Run Code Online (Sandbox Code Playgroud)

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

Aym*_*ieh 1464

要检查局部变量的存在:

if 'myVar' in locals():
  # myVar exists.
Run Code Online (Sandbox Code Playgroud)

要检查全局变量的存在:

if 'myVar' in globals():
  # myVar exists.
Run Code Online (Sandbox Code Playgroud)

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

if hasattr(obj, 'attr_name'):
  # obj.attr_name exists.
Run Code Online (Sandbox Code Playgroud)

  • 好的,我怎样才能检查课堂上存在的属性? (16认同)
  • 但OP正在键入代码,他们可以输入'myVar'而不是myVar.如果在编写代码时未知变量名,则它将在运行时存储在字符串变量中,并且我发布的检查也将起作用. (12认同)
  • 我最喜欢`if hasattr(obj,'attr_name'):`它也适用于类:即`if hasattr(self,'attr_name'):` (9认同)
  • 还有内置变量,如果你有嵌套函数,外部作用域中的变量.如果你想检查所有这些,你可能最好在触发`NameError`之后. (7认同)
  • 以及如何将可能不存在的变量名称转换为字符串? (6认同)
  • 请注意,从 [`hasattr`](https://docs.python.org/3.7/library/functions.html#hasattr) 的文档中:“这是通过调用 `getattr(object, name)` 并查看是否它是否引发“AttributeError”” - 因此它可能是显式捕获异常的更清晰的代码,但它可能不会更快。 (4认同)

pax*_*blo 113

使用未定义或设置的变量(隐式或显式)几乎总是在任何语言中都是坏事,因为它表明程序的逻辑没有被正确地思考,并且可能导致不可预测的行为.

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

try:
    myVar
except NameError:
    myVar = None

# Now you're free to use myVar without Python complaining.
Run Code Online (Sandbox Code Playgroud)

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

  • 状态变量在分配之前不存在 - 如果从前一个位置到当前位置绘制一条线,然后设置previous = current,这并不意味着您在第一次调用时"不知道您的变量".并且在绘制例程之外编写额外的代码行来初始化previous = null并不意味着你"更好地了解你的变量". (32认同)
  • "使用未定义的变量在任何语言中实际上都是一件坏事"让我看到居高临下的演讲.我们中的一些人使用Python进行简单的数学或统计脚本,使用像Spyder这样像IDE一样工作的IDE.在这些环境中,有时候允许用户在全局控制台中定义变量并检查脚本中是否未声明,就像在Matlab中进行数学运算一样. (18认同)
  • @Ricardo,也许,而不是假设它是屈尊俯就,你可能想要至少*考虑*这可能是来自*可能*更有知识的人的好建议:-)或者如果我建议反对,你会认为它同样是光顾吗?不受限制地使用全局变量,意大利面条代码,上帝对象,发布未经测试的代码或在COBOL中编写操作系统?我的回答说明了为什么我认为这是一个坏主意(并且问题中没有任何内容表明为什么OP认为这是必要的)但仍然提供了一种方法来解决他们真正想做的事情. (13认同)
  • 也许它是一个依赖的变量,根据它可能存在或不存在的版本/平台,并且没有其他方法可以知道它是什么版本. (7认同)
  • 我的观点是一个块"if last:draw(last,current); last = current"很容易理解,而且编程也不差.在能够测试之前添加"try/except"以检查"last"的存在会降低该代码的可读性. (4认同)
  • Python用于很多设置.我正在攻读数学博士学位.在Spyder的背景下,它是有道理的.这就像使用matlab. (3认同)
  • @paxdiablo在这种情况下,Python的创建者没有从VB获取页面并为我们这些喜欢编译时警告的运行时异常或崩溃的人提供某种"Option Explicit"(或者,可以说更糟糕的是,几个小时的不必要的调试). (2认同)
  • 尽管这在大多数程序中“几乎总是一件坏事”,但 Jupyter 笔记本是一个例外,其中对代码执行的顺序存在整体混乱,并且通常您想从内存中删除内容(使用 `del ...`),如果它仍然存在。无论如何,这就是我使用它的目的。谢谢! (2认同)

小智 40

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

然后是:

if myVar is not None:
    # Do something
Run Code Online (Sandbox Code Playgroud)

  • @jjisnow`if myVar:#that something`如果未声明myVar,则在python3中抛出`NameError` (7认同)
  • 在这个答案中有很多东西需要改进.相反 - 一种简单的方法是首先声明它.`myVar = none#do stuff ...如果不是myVar:#给myVar一个值myVar ='something' (2认同)
  • 为什么不是这样的: `if myVar: # Do something` 这避免了读取双重否定的需要 (2认同)
  • @jjisnow 因为即使`myVar` 是空列表、零、空字符串等,您也希望此条件为真。 (2认同)

小智 22

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

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

my_variable = None

def InitMyVariable():
  global my_variable
  if my_variable is None:
    my_variable = ...
Run Code Online (Sandbox Code Playgroud)

  • +1:请求宽恕比获得许可更好. (3认同)
  • 我尽量不使用它,因为它污染了全局命名空间.避免这种情况的一种方法是使函数成为一个类,my_variable作为一个类变量,并将__call__定义为现有函数的主体,但这是一个很难编码并打开一堆其他问题.我更喜欢使用函数属性,见下文. (2认同)

Wyr*_*ood 17

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

'var' in dir(obj)
Run Code Online (Sandbox Code Playgroud)

例如,

>>> class Something(object):
...     pass
...
>>> c = Something()
>>> c.a = 1
>>> 'a' in dir(c)
True
>>> 'b' in dir(c)
False
Run Code Online (Sandbox Code Playgroud)


sam*_*yse 11

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

class InitMyVariable(object):
  my_variable = None

def __call__(self):
  if self.my_variable is None:
   self.my_variable = ...
Run Code Online (Sandbox Code Playgroud)

我不喜欢这个,因为它使代码变得复杂并且打开了诸如这样的问题,这是否应该确认Singleton编程模式?幸运的是,Python允许函数暂时具有属性,这为我们提供了这个简单的解决方案:

def InitMyVariable():
  if InitMyVariable.my_variable is None:
    InitMyVariable.my_variable = ...
InitMyVariable.my_variable = None
Run Code Online (Sandbox Code Playgroud)


Sil*_*ost 9

catchexcept在Python中调用.除此之外,对于这种简单的案件来说这很好.还有的AttributeError,可以用来检查一个对象具有的属性.


Rog*_*ahl 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
  ...
Run Code Online (Sandbox Code Playgroud)

  • 概念上很好的解释,但可怕的用法例子. (3认同)

Abh*_*k R 5

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

def exists(var):
     return var in globals()
Run Code Online (Sandbox Code Playgroud)

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

exists("variable_name")
Run Code Online (Sandbox Code Playgroud)

将返回TrueFalse

  • 局部变量呢?也许也让该函数检查局部变量。 (2认同)