我想检查变量是否存在。现在我这样做:
1 2 3 4
| try:
myVar
except NameError:
# Do something. |
还有其他没有例外的方法吗?
- 有什么问题吗?
- @。洛特:如果myVar非常复杂,需要很长时间来生成/评估,那么try不会降低速度吗?
- 这是个变量。如果使用exec或元类做一些疯狂的事情,除了一些非常奇怪的情况外,它不会很昂贵。
- 更完整的答案是:stackoverflow.com/a/1592578/1661797
检查局部变量是否存在:
1 2
| if 'myVar' in locals():
# myVar exists. |
检查全局变量是否存在:
1 2
| if 'myVar' in globals():
# myVar exists. |
检查对象是否有属性:
1 2
| if hasattr(obj, 'attr_name'):
# obj.attr_name exists. |
- 好的,我如何检查类中存在的属性?
- 如何将可能不存在的变量名转换为字符串呢?
- @SilentGhost,你能详细说明一下还是举个例子?
- myVar是str, myVar是变量名。OP似乎没有myVar。
- 但是OP正在输入代码,他们可以输入'myVar'而不是myVar。如果在编写代码时不知道变量名,那么它将在运行时存储在一个字符串变量中,我所发布的检查也可以工作。
- 还有内置变量,如果您有嵌套函数,则外部作用域中也有变量。如果您想检查所有这些变量,最好还是触发NameError。
- 因为在Python中,class本身是一个实例,所以我可以检查类定义中是否存在变量。
- 您应该提到,hasattr不能可靠地告诉您属性是否存在。例如,当属性是属性并且访问该属性会引发异常时,hasattr的结果可能是错误的!
- 我最喜欢的if hasattr(obj, 'attr_name'):也适用于课堂:即if hasattr(self, 'attr_name'):
- 嗯。在循环中执行此操作(在数组中查找匹配的字符串元素)的处理成本非常高。我将使用下面的try-catch示例,因为它的处理开销最小。
- 这不适用于[] in globals()等不可撤销类型
- 请注意,从hasattr的文档中:"这是通过调用getattr(object, name)并查看它是否引发了一个AttributeError来实现的"——因此显式捕获异常的代码可能更干净,但可能不会更快。
在任何语言中,使用尚未定义或设置(隐式或显式)的变量几乎都是一件坏事,因为它表明程序的逻辑没有得到正确的考虑,并且可能导致不可预测的行为。
下面的技巧和你的很相似,可以确保变量在使用前有一定的值:
1 2 3 4 5
| try:
myVar
except NameError:
myVar = None
# Now you're free to use myVar without Python complaining. |
然而,我仍然不认为这是一个好主意——在我看来,您应该重构代码,这样才不会出现这种情况。
- 也许它是依赖关系的一个变量,根据版本/平台它可能存在也可能不存在,没有其他方法知道它是什么版本。
- 状态变量在赋值之前并不存在——如果您从上一个位置到当前位置画一条线,然后设置previous = current,这并不意味着您在第一次调用时"不知道您的变量"。在绘制例程之外编写额外的代码来初始化previous=null并不意味着您可以更好地"了解您的变量"。
- 不知道你想说什么,戴夫。你是对的,它们不存在,但在这种情况下,你不应该试图使用它们。确保它们确实存在,这就是我的建议。
- 我的观点是一个块"如果最后:绘制(最后,当前);last=current"易于理解,编程也不差。在能够测试"last"之前,添加"try/except"来检查它是否存在,这会降低代码的可读性。
- "if last: draw(last, current);如果last不存在,会导致异常吗?
- 在任何语言中,使用没有定义的变量实际上都是一件坏事。我们中的一些人使用Python编写简单的数学或统计脚本,使用ide(如Spyder),而ide的工作原理与Matlab类似。在这些环境中,有时允许用户在全局控制台中定义变量,并检查变量是否在脚本中未声明,这是有意义的,就像在Matlab中进行数学运算一样。
- @Ricardo,也许,而不是假设它是谦虚,至少你可能想要考虑的可能性,这只是好的建议可能更博学的人:-)或者你认为它同样傲慢如果我建议对无约束全局变量的使用,意大利面条式代码,上帝对象,释放未测试的代码,或者在COBOL编写操作系统吗?我的回答说明了为什么我认为这是一个坏主意(问题中没有说明为什么OP认为这是必要的),但仍然提供了一种可能性很小的方法,即他们真的想这么做。
- Python在很多设置中都被使用。我在攻读数学博士学位。在Spyder的上下文中,这是有意义的。就像用matlab一样。
- @paxdiablo在这种情况下,Python的创建者没有从VB中吸取经验教训,为我们这些喜欢编译时警告而不喜欢运行时异常或崩溃的人提供某种Option Explicit,这实在是太糟糕了(更糟的是,这可能会导致几个小时不必要的调试)。
- 支持@RicardoCruz注释:当脚本可以在pyspark-shell内运行或从spark-submit运行时,代码if not sc:将处理后一种情况,这也很有意义。除了python抱怨NameError: sc is not defined
- @paxdiablo,你对未来代码的使用有多严格?单独在家并始终以相同的方式运行它与让一个社区包含您的模块、或者直接从shell或runpy.run_path执行模块是不同的。此外,事件驱动的编程可能要求您不知道以前到底做了什么。我同意这"很可能导致不可预测的行为",这取决于我们对可能的情况进行方便的测试
- 洛伦佐,你是对的,当我只为了自己的目的编写代码时,我对正确性的要求更加宽松(因为我可以很容易地动态调试问题)。然而,这不是我发布的代码所以:-)
一种简单的方法是首先用myVar = None初始化它
之后:
1 2
| if myVar is not None:
# Do something |
- 这个答案有很多需要改进的地方。相反,一个简单的方法是首先声明它。myVar = none # do stuff... if not myVar: # give myVar a value myVar = 'something'
- 我非常喜欢这个,因为我在我的except语句中设置了None
- 为什么不这样写:if myVar: # Do something这样可以避免读双重否定
- @jjisnow因为您希望这个条件为真,即使myVar是一个空列表、0、空字符串等。
- 如果没有声明myVar, @jjisnow if myVar: # Do something将在python3中抛出NameError
使用try/except是测试变量是否存在的最好方法。但是几乎可以肯定,有比设置/测试全局变量更好的方法。
例如,如果您想在第一次调用某个函数时初始化模块级变量,那么最好编写这样的代码:
1 2 3 4 5 6
| my_variable = None
def InitMyVariable():
global my_variable
if my_variable is None:
my_variable = ... |
- 金币1 .请求原谅总比得到允许好。
- 我尽量不使用它,因为它会污染全局名称空间。避免这种情况的一种方法是使函数成为一个类,以my_variable作为类变量,并将call定义为现有函数的主体,但是编写代码很麻烦,还会引发一系列其他问题。我更喜欢使用函数属性,如下所示。
对于对象/模块,也可以
例如,
1 2 3 4 5 6 7 8 9
| >>> class Something(object):
... pass
...
>>> c = Something()
>>> c.a = 1
>>> 'a' in dir(c)
True
>>> 'b' in dir(c)
False |
我将假设这个测试将在一个函数中使用,类似于user97370的答案。我不喜欢这个答案,因为它会污染全局名称空间。修复它的一种方法是使用一个类:
1 2 3 4 5 6
| class InitMyVariable(object):
my_variable = None
def __call__(self):
if self.my_variable is None:
self.my_variable = ... |
我不喜欢这样做,因为这样会使代码变得复杂,并引发一些问题,比如,这是否应该与单例编程模式相一致?幸运的是,Python允许函数有属性已经有一段时间了,这给了我们一个简单的解决方案:
1 2 3 4
| def InitMyVariable():
if InitMyVariable.my_variable is None:
InitMyVariable.my_variable = ...
InitMyVariable.my_variable = None |
在Python中,catch被称为except。除此之外,对于这种简单的情况也可以。可以使用AttributeError检查对象是否具有属性。
它只是对前面的答案的一个补充,用于检查键是否以JSON/Dict的形式出现在python中
"Json / Dict对象名称"。has_key(密钥名)
这将返回True或False
一种处理这种情况的好方法是不显式地检查变量是否存在,而是直接在try/except NameError中封装可能不存在的变量的第一个用法:
1 2 3 4 5 6 7 8 9 10 11 12 13
| # 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
... |