Determine if variable is defined in Python
Possible Duplicate:
Easy way to check that variable is defined in python?
How do I check if a variable exists in Python?
如何知道在运行时是否在代码中的特定位置设置了变量?这并不总是显而易见的,因为(1)可以有条件地设置变量,(2)可以有条件地删除变量。我在寻找Perl中的defined()或PHP中的isset()或Ruby中的defined?。
1 2 3 4 5 6 7 8 9
| if condition:
a = 42
# is"a" defined here?
if other_condition:
del a
# is"a" defined here? |
- 重复项:stackoverflow.com/questions/843277/…,stackoverflow.com/questions/750298/…,
- 请不要"有条件地"设置变量。那只是一个可怕的,可怕的设计。总是,总是,总是提供所有的逻辑路径。请不要继续这样做。
- +1至S.Lott Anwser。事实上,有一种方法可以做到这一点并不意味着你应该在一个新的项目中使用它。
- @洛特:我不同意。当我使用import来"源"一个"配置文件"(即只有赋值的文件)时,很可能其中没有定义某个变量。而且import肯定比ConfigParser便宜/简单,所以对我来说实用主义战胜了美。
- @状态访问被拒绝:这就是默认值是合适的。首先设置默认值。然后导入配置。现在,所有变量都被定义为配置文件中的默认值或覆盖值。您可以轻松避免有条件地设置变量。
- @洛特:用记忆法怎么样?您可以有条件地返回或设置。这是鲁比的性病,所以我才来这里。
- 这是个愚蠢的问题,我知道我想得太多了…通过"有条件地设置一个变量",你是说一个变量的存在不应该基于一个条件吗?
- "丹尼尔,是的。您可能会认为"如果not condition的话,这个变量永远不会被引用",但是已经一次又一次地(至少是个人经验)表明程序员不完善,逻辑流实际上可能与预期不同。这在螺旋式开发中尤其如此,在这种开发中,假设会发生变化,而不是所有代码都会被审计/重构。即使只在满足condition的情况下使用,设置变量也"几乎不需要"任何费用。
- @0XC00000022L进口机械重。不用于"配置文件"。如果这是你唯一想要的,你最好使用exec或eval。然而,这在很多方面是非常不安全的,所以我认为它值得一个简单的解析器。无论如何,最接近的等同于isset()的是hasattr()。也可以使用能够返回违约的globals().get()。
1 2 3 4 5 6
| try:
thevariable
except NameError:
print"well, it WASN'T defined after all!"
else:
print"sure, it was defined." |
- @亚伦:很多情况下,你不知道变量是否被定义。您可以重构代码以在许多情况下(但并非所有情况下)避免这种情况。亚历克斯的解决方案是正确的,最好是由于某些原因而无法重构。这个问题没有太多的信息,所以我相信只有被问到的人才能选择最好的方式来处理他的案件。
- @Aaron,"应该"是一个4个字母的词——例如,没有一个司机"应该"超过限速,但这并不意味着你没有采取所有适当和必要的预防措施来对付那些仍然这样做的人。用你从别人那里继承的有点破烂的设计来维护脆弱的、未被重视的遗留代码是生活的一个事实,那些只能从零开始考虑"大爆炸"重写的人,而不是谨慎而渐进地重新阅读乔尔9岁的文章joelonsoftware.com/articles/fog000000069.html。
- @s.lott人们使用它来保持向后兼容性。在python 3.1源代码中搜索nameerror。有许多实例使用了"try:varu name except nameerror:somethingu else"。这里有几个地方使用它:csv(svn.python.org/projects/python/trunk/lib/csv.py)库和elementtree库(svn.python.org/projects/python/trunk/lib/xml/etree/…)。
- 这个争论更有趣的是,答案本身是100%正确的,并且让您优雅地处理糟糕的遗留代码。
- 它取决于上下文,例如,在脚本环境中,检查是否定义了变量以及是否定义了变量是非常好的。给它一个默认值。我的2C。
- @s.lott-视图模板中的变量是什么样的,要设置该变量需要使用include代码吗?在这些情况下,如何确保定义的变量?
- 变量也可以动态定义,我不希望脚本停止工作,因为只有在发生"x"时才正确定义了变量。投票!
- 注意:如果它是一个类属性,则需要使用try:self.myMissingVar except attributeError:print'它不在那里!'
- 其他答案中的大部分讨论都假定问题在于如何判断符号是否具有初始值,而OP则明确指出问题在于符号是否具有任何值。"无"是一个值,因此其值为"无"的符号的值为"完全"。
- [继续]这就是为什么需要使用try或checking globals()。示例:您有一个执行重要初始化计算的文件,该文件的结果要分配给全局符号。您希望能够从许多模块中的任何一个模块执行文件/exec(python 2/3),其中一些模块可能用于多个程序。但是,您只希望在程序执行期间执行一次初始化。解决方案:将exec file/exec放在所需的任意位置,并将文件的内容包装在一个条件中,该条件测试它定义的某个符号是否具有值。
- 例外情况应保留在例外情况下,不能用作"if"的私生子兄弟。-(
- 另请参见有关何时使用异常的一般性讨论。
- 元讨论链接到此答案meta.stackoverflow.com/q/289938/73226
- @在每个for语句中,python都使用异常StopIteration,这就是迭代器让它知道一切都已完成的方式。当然,要完成迭代还远远不是"一个例外情况"——事实上,人们期望大多数迭代都会终止。因此,很明显,您对如何使用异常"应该"的看法不适用于Python(其他语言具有不同的语用学,并且问题不能像您所指的Q那样被正确地视为"语言不可知论")。
- 我同意@alexmartelli的观点:拥有未定义变量的能力是Python的一个特性。作为任何特性,它都有一些或多或少合适的用例。但这绝对不合适。对其进行定义或不定义的测试并不比测试文件的存在更奇怪。而python非常注重duck类型,使用异常非常有意义。顺便说一句,例外的是if:s的私生子兄弟。
- @habnabit easy rebutal:我正在使用iniparse加载配置文件,但要确保设置了某些变量,否则程序无法继续。
- 在使用pyspark和jupiter(它确实为你定义了sparkcontext为sc)以及meos(它没有)时,偶然发现了这个问题。这就是为什么我们有时需要这个。
- python在jupyter笔记本中用于交互式数据分析。在这种情况下,在可能重新加载或重新计算一个昂贵的变量之前添加一个检查变量是否被定义的检查是非常好的,因为您更改了单元中的另一部分代码并重新评估了它。
- @shadur不相关;iniparse不设置变量。
'a' in vars() or 'a' in globals()
如果你想去,你可以检查pedantic,内置了'a' in vars(__builtins__)
- 这应该是我相信的答案。请参阅stackoverflow.com/questions/843277/…
- 这是一个非常惯用的答案。这里有一个强大的地图用例;例如,if"prop2" in {"prop0": None,"prop1": None}:
- 这个答案也适用于检测变量以外的成员,比如函数、类和模块。
- 截至今天-2018年6月:我认为vars(__builtin__)仍然不起作用(对于Python2或3)。我相信EDOCX1(注意复数;-)现在应该用于这两个版本(在:python 2.7.10和python 3.6.1上测试)。
- @菲利普。谢谢。更新了答案
- 为什么不使用locals(),为什么不使用dir()?
我认为它的更好,以避免的情况。它的清洁和clearer写:
1 2 3
| a = None
if condition:
a = 42 |
- 如果你想这样做,你应该使初始值是唯一的,这样你就可以区别于设置a到None的东西,即UNDEFINED=object();a=UNDEFINED,然后你可以用a is not UNDEFINED进行测试。
- 这是"无"的常用用法。从字面上看,它是"无"的语义含义——什么都不是,纳达,zip。它存在,但"没有价值"。如果一个任务中没有一个值,那么使用一个非无值是很有用的,等等,但是这并不常见,所以避免一个值都不应该是标准实践。例如,在这个问题中,a只能是42或未定义的。将"未定义"更改为"无"值不会导致信息丢失。
- 这就是为什么人们认为使用一个长而脏的try/except构造来完成这项工作的原因,但不清楚。在类成员函数中使用关键字args时,如果不想将默认值硬编码到参数列表中(只需将默认值定义为类成员),则这非常有用。
- @Devinjeanpierre那不一定是真的。如果要为JSON API创建一些客户端库,将null值视为与未指定值不同的值(例如,None将实际JSON值设置为null,而未指定值则将其完全从JSON消息中删除,从而使API使用默认值或从其他属性中计算),则需要她将None与Undefined或None与json null区分开来。认为None不能或不应该被用作与明确未指定或未定义的值不同的值,是非常短视的。
- "泰威当然可以。"如果一个任务中没有一个值可以出现,那么使用非无值是很有用的,但是这并不常见,因此避免一个值应该是标准实践。"如果一个非无值可以出现,那么就没有一个值是不可接受的,而且整个模式很容易出错。"
- 提供一个默认值(这个答案就是这样做的)与测试变量的存在有很大的不同。用例中可能有很多重叠,但是如果您想查看是否已经定义了一些东西,您将永远不会知道这个方法。
1 2 3 4
| try:
a # does a exist in the current namespace
except NameError:
a = 10 # nope |
- 例外情况只能在例外情况下使用。查看此讨论
- @Einpoklum对于大多数语言都是这样的,但是在Python中,使用异常的频率更高,请参见stackoverflow.com/questions/3086806。
- 嗯,很奇怪,但很明显是真的。我仍然认为这不是一个好主意(TM),但是,好吧,不能与社区习俗争论。
- 最好使用上面提到的if 'a' in vars() or 'a' in globals()解决方案,不需要例外
- Try/Except是您在Python中所做的。一种语言中的代码气味是另一种语言的特征。
一个可能的情况,这可能是必要的。
如果你是用finally块可在关闭连接try程序块退出,sys.exit()定义为在与连接。在这个案例,将被称为finally块和语句将失败,因为连接关闭的连接被创建。
在这个特殊的案例,它的更好的del aa = None来代替。这将是对对象的引用计数a减量(如有)的分配和a不会失败时,是不确定的。注意,不是del语句的析构函数调用一个对象的直接变量,但是可以从解放。一个被称为析构函数的时候,对象所在的参考计数为零。
如果想吸引到一个访问的非诸因素定义的变量内的物件,有一个非常简单的方式这样做。
1 2 3
| class Whatever(object):
def __getattr__(self, key):
return None |
在这里,第一tries找到Python属性在对象或对象的树,如果是在一个被称为__getattr__(self, key)函数失败。这一个被称为__getattr__均值,如果我们可以简单的返回None。
- -在查找字典之前调用1 __getattr__。
- @量子不,不是,但在查字典之前,会先调用__getattribute__。