为什么在Python中给全局变量赋值无效?
我在理解Python的作用域规则时遇到了很大的困难。
看这个脚本:
a = 7
def printA():
print "Value of a is %d" % (a)
def setA(value):
a = value
print "Inside setA, a is now %d" %(a)
print "Before setA"
printA()
setA(42)
print "After setA"
printA()
它给出的输出让我感到意外:
Before setA Value of a is 7 Inside setA, a is now 42 After setA Value of a is 7
我本来期待最后打印出来的a的值是42,而不是7。我对Python的全局变量作用域规则有什么误解吗?
6 个回答
5
在这个函数里面,a 被当作一个局部变量来处理。你需要在使用它之前,先在函数里面定义一下
global a
即使你在函数外面已经定义过它。
15
理解这个问题的关键在于,当你用 = 给一个变量赋值时,你同时也把它声明为一个局部变量。所以,setA(value) 这个函数并不是在改变全局变量 a 的值,而是把一个叫做 a 的局部变量设置为传入的值。
如果你在 setA(value) 函数开始的时候尝试打印 a 的值,你会更容易明白这一点:
def setA(value):
print "Before assignment, a is %d" % (a)
a = value
print "Inside setA, a is now %d" % (a)
如果你运行这个代码,Python 会给你一个很有帮助的错误提示:
Traceback (most recent call last): File "scopeTest.py", line 14, in setA(42) File "scopeTest.py", line 7, in setA print "Before assignment, a is %d" % (a) UnboundLocalError: local variable 'a' referenced before assignment
这个错误告诉我们,Python 认为 setA(value) 函数里有一个叫做 a 的局部变量,而你在函数里赋值时就是在改变这个局部变量。如果你在函数里没有给 a 赋值(就像在 printA() 函数里那样),那么 Python 就会使用全局变量 A。
如果你想把一个变量标记为全局变量,你需要在 Python 中使用 global 这个关键字,在你想使用全局变量的范围内。在这个例子中,就是在 setA(value) 函数内部。所以代码变成了:
a = 7
def printA():
print "Value of a is %d" % (a)
def setA(value):
global a
a = value
print "Inside setA, a is now %d" %(a)
print "Before setA"
printA()
setA(42)
print "After setA"
printA()
这一行的添加告诉 Python,当你在 setA(value) 函数中使用变量 a 时,你指的是全局变量,而不是局部变量。