Python全局变量在函数中的if语句评估时不起作用
示例 1:
a=1
def b():
print a
a=2
print a
示例 2:
a=1
def b():
print a
if a==1:
a=2
print a
示例 1 按预期工作,而示例 2 在第一次打印 a 时出错,提示 UnboundLocalError: 本地变量 'a' 在赋值前被引用。
有人能解释一下为什么会这样吗?这是个错误还是一种特性?
第二个示例不是很有用,但我不明白为什么它不应该工作。我本以为函数 b 会先打印全局变量 a,然后检查全局变量 a 是否为 1。如果是这样,本地变量 a 会被设置为 2。然后根据全局变量 a 的值,可能会打印全局变量 a 或本地变量 a。在这个例子中,全局变量 a 是 1,所以我本以为会看到本地变量 a 打印出 2 的值。
示例 3:
a=1
def b():
print a
工作正常
示例 4:
a=1
def b():
print a
a=2
失败了,示例 1 也失败了,正如评论中所说的,我其实只测试了示例 3,并认为它和示例 1 是一样的。
现在我明白了关于作用域的那些反复提到的事情。这对我来说完全是新鲜事,我对下面这个例子感到很有趣(Ipython):
In [13]: a=1
In [14]: def b():
....: a=2
....: global a
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
....: print a
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
....:
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
<input>:3: SyntaxWarning: name 'a' is assigned to before global declaration
<ipython-input-14-4fe1c6cdc9d0>:3: SyntaxWarning: name 'a' is assigned to before global
declaration
global a
In [15]: b()
2
In [16]: print a
2
所以这个机制和声明一个函数或类似的事情不同,在我改变状态之后才能访问它。
在 Python 中还有其他类似的操作吗?就像是穿越时间一样?
为了让这些示例正常工作,可以使用 globals():
示例 1 正常工作:
a=1
def b():
print globals()["a"]
a=2
print a
示例 2 正常工作:
a=1
def b():
global_a=globals()["a"]
print global_a
if global_a==1:
a=2
print a
示例 4 正常工作:
a=1
def b():
print globals()["a"]
a=2
相关问题:
1 个回答
4
在Python中,名字的作用范围是根据赋值来决定的,这个决定是在代码解析的时候做的。如果你给一个名字赋值,那么在整个作用范围内,它就是局部的。比如你在函数b()里给赋值,所以就是局部变量,永远不会被当作全局变量来看待。
在这种情况下,你需要明确告诉解析器把当作全局变量来处理:
def b():
global a
print a
if a==1:
a=2
print a
注意,你的第一个例子也会出现完全相同的错误;因为在那个版本中你也在赋值,所以它也会引发UnboundLocalError错误:
>>> a=1
>>> def b():
... print a
... a=2
... print a
...
>>> b()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in b
UnboundLocalError: local variable 'a' referenced before assignment