确定变量是否在Python中定义

use*_*008 380 python variables defined

可能重复:
检查变量是否在python中定义的简单方法?
如何检查Python中是否存在变量?

您如何知道变量是否已在运行时在代码中的特定位置设置?这并不总是显而易见的,因为(1)变量可以有条件地设置,(2)变量可以有条件地删除.我正在寻找像defined()Perl isset(),PHP或defined?Ruby中的东西.

if condition:
    a = 42

# is "a" defined here?

if other_condition:
    del a

# is "a" defined here?
Run Code Online (Sandbox Code Playgroud)

Ale*_*lli 595

try:
    thevariable
except NameError:
    print("well, it WASN'T defined after all!")
else:
    print("sure, it was defined.")
Run Code Online (Sandbox Code Playgroud)

  • @Aaron,"应该"是一个4个字母的单词 - 例如没有司机"应该"超过速度限制,但这并不意味着你没有对那些做过的人采取所有适当和必要的预防措施.维护脆弱的,遗留下来的代码与你从其他人那里继承的有点破碎的设计是生活中的事实,那些只能从头开始而不是谨慎和渐进地想到重大改写的人需要重新阅读乔尔的9年-old文章http://www.joelonsoftware.com/articles/fog0000000069.html. (138认同)
  • @Aaron:有很多情况下你不知道是否定义了变量.您可以在许多情况下重构代码以避免这种情况,但不是所有情况.Alex的解决方案是正确的,并且由于某些原因无法进行重构时效果最佳.问题中没有太多信息,所以我相信只有人问它可以选择处理他的案件的最佳方式. (74认同)
  • 这个辩论更有趣的是答案本身,顺便说一句是100%正确,让你优雅地处理糟糕的遗留代码. (20认同)
  • @einpoklum,**Python**在****每个**`for`语句中使用异常`StopIteration` - 这就是迭代器让它知道它已完成的方式.当然,对于迭代来说,它距离"特殊情况"是远远的 - 实际上,人们期望*大多数*迭代终止.因此,很明显,你对如何"应该"使用异常的看法**不适用于******(其他语言有不同的语用,问题**不能被正确地视为"语言不可知"就像在Q中指出的那样). (14认同)
  • 例外情况应保留用于特殊情况,不得用作'if'的混蛋兄弟:--( (11认同)
  • @ S.Lott人们使用它来保持向后兼容性.在Python 3.1源代码中搜索NameError.有许多实例使用"try:var_name除NameError:something_else".以下是使用它的几个地方:CSV(http://svn.python.org/projects/python/trunk/Lib/csv.py)库和ElementTree库(http://svn.python).组织/项目/蟒蛇/主干/库/ XML/etree/ElementTree.py). (10认同)
  • 它取决于上下文,在脚本环境中,例如,检查变量是否定义,以及广告是完全正确的.ES.给它一个默认值.我的2c. (3认同)
  • 另见SO上[何时使用例外](http://stackoverflow.com/q/77127/1593077)的一般性讨论. (3认同)
  • 我同意@AlexMartelli:具有未定义变量的能力是Python中的*特征*.作为任何功能,它有一些或多或少适合的用例.但它肯定*从来都不合适.测试它是否被定义并不比测试文件的存在更奇怪.Python非常关注鸭子打字,使用异常非常有意义.顺便说一句,异常*是*if的私生子兄弟. (3认同)
  • @ S.Lott - 视图模板中的变量如何,由设置变量的包含代码决定?在这些情况下,您如何确保定义的变量? (2认同)
  • 变量也可以动态定义,我不希望我的脚本停止工作只是因为只有在"x"发生时才能正确定义变量.给予好评! (2认同)
  • 其他答案中的大部分讨论都假设问题是如何判断符号是否具有初始值,而 OP 明确表示问题实际上是符号是否具有任何值。None 是一个值,因此值为 None 的符号确实具有“根本”值。 (2认同)
  • 链接到这个答案的元讨论 http://meta.stackoverflow.com/q/289938/73226 (2认同)

Joh*_*ooy 320

'a' in vars() or 'a' in globals()

如果你想迂腐,你也可以查看内置的
'a' in vars(__builtins__)

  • 这应该是我相信的答案.请参阅http://stackoverflow.com/questions/843277/python-checking-variable-existing (19认同)
  • 这是一个非常惯用的答案。这里有一个强大的地图用例;例如,如果{{prop0“中的” prop2“:无,” prop1“:无}: (2认同)
  • **截至今天**-2018年6月**:我认为`vars(__ builtin __)`仍然不起作用(适用于Python 2或3)。我相信现在应该在两个版本中都使用vars(__ builtins__)_(注意复数;-))_(在Python 2.7.10和Python 3.6.1上测试)。 (2认同)
  • 为什么也不要locals(),为什么也不要dir()? (2认同)
  • @AndresVia `globals()` 是 `locals()` 的超集。 (2认同)

div*_*eek 120

我认为最好避免这种情况.写起来更清晰,更清晰:

a = None
if condition:
    a = 42
Run Code Online (Sandbox Code Playgroud)

  • 这是None的常见用法.它实际上是None的语义含义 - 它没什么,nada,zip.它存在,但"没有价值".如果None可以出现在赋值等中,则使用非None值非常有用,但这并不常见,因此避免None应该是标准做法.例如,在问题中,a只会是42或未定义.将undefined更改为None值会导致信息丢失. (14认同)
  • 如果你喜欢这样做,你应该使初始值唯一,这样你就可以区别于设置`a`到'None`的东西.`UNDEFINED = object(); a = UNDEFINED`然后你可以测试`a is not UNDEFINED` (7认同)
  • 这是方式,不知道为什么人们认为使用LONG和DIRTY try/except构造来完成这项工作.在类成员函数中使用关键字args时,这非常有用,您不希望将默认值硬编码到参数列表中(您只需将默认值定义为类成员). (5认同)
  • 提供默认值(这是答案正在做的)与测试变量的存在有很大不同.用例中可能存在很多重叠,但如果您想查看是否已定义某些内容,您将永远不会知道此方法. (4认同)

sc4*_*c45 16

try:
    a # does a exist in the current namespace
except NameError:
    a = 10 # nope
Run Code Online (Sandbox Code Playgroud)

  • @einpoklum大多数语言都是如此,但在Python中更常使用异常,例如http://stackoverflow.com/questions/3086806 (13认同)
  • 例外情况只应在特殊情况下使用.见[本讨论](http://stackoverflow.com/q/77127/1593077) (6认同)
  • 最好在上面提到的globals()`解决方案中使用vars()中的`if'a'或'a',这不需要例外 (3认同)
  • 嗯,很奇怪但很明显,显然.我仍然认为这不是一个好主意(TM),但是,不能与社区习俗争论. (2认同)

Den*_*ach 5

对于这种特殊的情况下,它是好做a = None的,而不是del a.这将减少对象的引用计数a(如果有)分配给,并且在a未定义时不会失败.注意,该del语句不直接调用对象的析构函数,而是从变量中取消绑定.当引用计数变为零时,将调用对象的析构函数.


xsr*_*ity 5

可能需要这种情况的一种可能情况:

如果使用finally块来关闭连接,但在try块中,程序sys.exit()将在定义连接之前退出.在这种情况下,finally将调用该块,并且连接关闭语句将失败,因为未创建任何连接.