我在尝试理解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的全局变量范围规则缺少什么?
答案 0 :(得分:113)
全局变量很特殊。如果尝试在函数内部分配变量a = value
,它会在函数内部创建一个新的局部变量,即使存在具有相同名称的全局变量也是如此。要改为访问全局变量,请在函数内添加global
statement:
a = 7
def setA(value):
global a # declare a to be a global
a = value # this sets the global value of a
另请参阅Naming and binding以获取有关Python命名和绑定规则的详细说明。
答案 1 :(得分:12)
理解这一点的技巧是,当你使用=分配给变量时,你也将它声明为局部变量。因此,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时,你正在谈论全局变量,而不是局部变量。
答案 2 :(得分:1)
Python没有像其他语言那样的变量概念。您有“某处”的对象,并且您具有对这些对象的引用。 =用于将这些对象分配给当前命名空间中的引用。
您在setA函数的名称空间中创建名称a,该名称引用值所引用的对象。
答案 3 :(得分:1)
在函数内部, a 被视为局部变量,需要定义
全球a
在函数内部
答案 4 :(得分:0)
函数的执行引入了一个新的符号表,用于该函数的局部变量。更准确地说,函数中的所有变量分配都将值存储在本地符号表中。变量引用首先在本地符号表中查找,然后在封闭函数的本地符号表中查找,然后在全局符号表中查找,最后在内置名称表中查找。因此,尽管可以引用全局变量,但不能在函数内直接为其赋值(除非在全局语句中命名)。