I'm having terrible trouble trying to understand python scoping rules.
我在尝试理解python范围规则时遇到了很大的麻烦。
With the following script:
下面的脚本:
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()
Gives the unexpected (to me) output of:
给(我)意想不到的输出:
Before setA Value of a is 7 Inside setA, a is now 42 After setA Value of a is 7
Where I would expect the last printing of the value of a to be 42, not 7. What am I missing about Python's scope rules for the scoping of global variables?
最后一次输出a的值是42,而不是7。对于Python的全局变量范围规则,我缺少什么?
4 个解决方案
#1
101
Global variables are special. If you try to assign to a variable a = value
inside of a function, it creates a new local variable inside the function, even if there is a global variable with the same name. To instead access the global variable, add a global
statement inside the function:
全局变量是特别的。如果您试图将一个变量赋值给一个函数,它会在函数内部创建一个新的局部变量,即使有一个具有相同名称的全局变量。若要访问全局变量,请在函数中添加一个全局语句:
a = 7
def setA(value):
global a # declare a to be a global
a = value # this sets the global value of a
See also Naming and binding for a detailed explanation of Python's naming and binding rules.
有关Python的命名和绑定规则的详细说明,请参见命名和绑定。
#2
11
The trick to understanding this is that when you assign to a variable, using =, you also declare it as a local variable. So instead of changing the value of the global variable a, setA(value) actually sets a local variable (which happens to be called a) to the value passed in.
理解这一点的诀窍是,当您使用=分配一个变量时,您也将它声明为一个局部变量。因此,setA(value)并没有改变全局变量a的值,而是设置了一个本地变量(碰巧被称为a)。
This becomes more obvious if you try to print the value of a at the start of setA(value) like so:
如果您尝试在setA(value)的开头打印a的值,这就变得更加明显:
def setA(value):
print "Before assignment, a is %d" % (a)
a = value
print "Inside setA, a is now %d" % (a)
If you try to run this Python will give you a helpful error:
如果您试图运行这个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
This tells us that Python has decided that the setA(value) function has a local variable called a, which is what you alter when you assign to it in the function. If you don't assign to a in the function (as with printA()) then Python uses the global variable A.
这告诉我们,Python已经决定setA(value)函数具有一个称为a的局部变量,当您在函数中为它赋值时,就会修改这个局部变量。如果在函数中没有赋值给a(与printA()一样),那么Python使用全局变量a。
To mark a variable as global you need to use the global keyword in Python, in the scope that you want to use the global variable. In this case that is within the setA(value) function. So the script becomes:
要将一个变量标记为全局变量,您需要在Python中使用全局关键字,在您希望使用全局变量的范围内。在本例中,它位于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()
This one line addition tells Python that when you use the variable a in the setA(value) function that you are talking about the global variable, not a local variable.
这一行的添加告诉Python,当您在setA(value)函数中使用变量a时,您所谈论的是全局变量,而不是局部变量。
#3
2
Python does not have a concept of variables as other languages. You have objects which are "somewhere" and you have references to these objects. = is used to assign these objects to references in the current namespace.
Python不像其他语言一样有变量的概念。你有“某处”的对象,你有对这些对象的引用。=用于将这些对象分配给当前名称空间中的引用。
You create a name a in the namespace of the setA function which refers to the object to which value refers.
您可以在setA函数的名称空间中创建一个名称a,它引用的对象是值引用的对象。
#4
1
inside the function,a is treated as a local variable,you need to define
在函数内部,a被视为局部变量,需要定义
global a
全球一
inside the function
内部函数
#1
101
Global variables are special. If you try to assign to a variable a = value
inside of a function, it creates a new local variable inside the function, even if there is a global variable with the same name. To instead access the global variable, add a global
statement inside the function:
全局变量是特别的。如果您试图将一个变量赋值给一个函数,它会在函数内部创建一个新的局部变量,即使有一个具有相同名称的全局变量。若要访问全局变量,请在函数中添加一个全局语句:
a = 7
def setA(value):
global a # declare a to be a global
a = value # this sets the global value of a
See also Naming and binding for a detailed explanation of Python's naming and binding rules.
有关Python的命名和绑定规则的详细说明,请参见命名和绑定。
#2
11
The trick to understanding this is that when you assign to a variable, using =, you also declare it as a local variable. So instead of changing the value of the global variable a, setA(value) actually sets a local variable (which happens to be called a) to the value passed in.
理解这一点的诀窍是,当您使用=分配一个变量时,您也将它声明为一个局部变量。因此,setA(value)并没有改变全局变量a的值,而是设置了一个本地变量(碰巧被称为a)。
This becomes more obvious if you try to print the value of a at the start of setA(value) like so:
如果您尝试在setA(value)的开头打印a的值,这就变得更加明显:
def setA(value):
print "Before assignment, a is %d" % (a)
a = value
print "Inside setA, a is now %d" % (a)
If you try to run this Python will give you a helpful error:
如果您试图运行这个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
This tells us that Python has decided that the setA(value) function has a local variable called a, which is what you alter when you assign to it in the function. If you don't assign to a in the function (as with printA()) then Python uses the global variable A.
这告诉我们,Python已经决定setA(value)函数具有一个称为a的局部变量,当您在函数中为它赋值时,就会修改这个局部变量。如果在函数中没有赋值给a(与printA()一样),那么Python使用全局变量a。
To mark a variable as global you need to use the global keyword in Python, in the scope that you want to use the global variable. In this case that is within the setA(value) function. So the script becomes:
要将一个变量标记为全局变量,您需要在Python中使用全局关键字,在您希望使用全局变量的范围内。在本例中,它位于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()
This one line addition tells Python that when you use the variable a in the setA(value) function that you are talking about the global variable, not a local variable.
这一行的添加告诉Python,当您在setA(value)函数中使用变量a时,您所谈论的是全局变量,而不是局部变量。
#3
2
Python does not have a concept of variables as other languages. You have objects which are "somewhere" and you have references to these objects. = is used to assign these objects to references in the current namespace.
Python不像其他语言一样有变量的概念。你有“某处”的对象,你有对这些对象的引用。=用于将这些对象分配给当前名称空间中的引用。
You create a name a in the namespace of the setA function which refers to the object to which value refers.
您可以在setA函数的名称空间中创建一个名称a,它引用的对象是值引用的对象。
#4
1
inside the function,a is treated as a local variable,you need to define
在函数内部,a被视为局部变量,需要定义
global a
全球一
inside the function
内部函数