Python中将自由变量视为全局变量?
在Python3.7参考手册的最后部分,我阅读了以下语句:Python中将自由变量视为全局变量?,python,python-3.x,scope,globals,free-variable,Python,Python 3.x,Scope,Globals,Free Variable,在Python3.7参考手册的最后部分,我阅读了以下语句: global语句与同一块中的名称绑定操作具有相同的作用域。如果自由变量的最近封闭范围包含global语句,则该自由变量将被视为全局变量 因此,我在Python解释器中键入了以下代码: x =0 def func1(): global x def func2(): x = 1 func2() 调用func1()后,我希望全局范围内的x的值更改为1 我做错了什么?func2中的x=1不是自由变量。这
global
语句与同一块中的名称绑定操作具有相同的作用域。如果自由变量的最近封闭范围包含global
语句,则该自由变量将被视为全局变量
因此,我在Python解释器中键入了以下代码:
x =0
def func1():
global x
def func2():
x = 1
func2()
调用func1()
后,我希望全局范围内的x
的值更改为1
我做错了什么?
func2
中的x=1
不是自由变量。这只是另一个地方性问题;您将绑定到名称,并且默认情况下,绑定到的名称是局部变量,除非您告诉Python其他情况
从:
如果名称绑定在块中,则它是该块的局部变量,除非声明为非局部
或全局
。[…]如果在代码块中使用了变量,但未在代码块中定义,则该变量为自由变量。
(粗体强调)
您将块中的名称与x=1
绑定,因此它是该块中的局部变量,不能是自由变量。所以您找到的部分不适用,因为它只适用于自由变量:
如果自由变量的最近封闭范围包含global
语句,则将自由变量视为全局变量
您不应该在func2()
中绑定x
,因为只有在作用域中未绑定的名称才是自由变量
所以这是可行的:
>>> def func1():
... global x
... x = 1
... def func2():
... print(x) # x is a free variable here
... func2()
...
>>> func1()
1
>>> x
1
func2
中的x
现在是一个自由变量;它未在func2
的作用域中定义,因此从父作用域中选取它。此处的父作用域是func1
,但是x
标记为全局,因此在读取print()
函数的x
时,将使用全局值
这与x
在func1
中未标记为全局相比:
>>> def func1():
... x = 1
... def func2():
... print(x) # x is free variable here, now referring to x in func1
... func2()
...
>>> x = 42
>>> func1()
1
此处全局名称x
设置为42
,但这不会影响打印内容<func2
中的code>x是一个自由变量,但父作用域func1
只有x
作为本地名称
当您添加一个新的最外层作用域,其中x
仍然是本地的时,它会变得更加有趣:
outerfunc
中的x
已绑定,因此不是自由变量。因此,这是该范围内的一个局部问题。但是,在func1
中,global x
声明在嵌套的scrop中将x
标记为全局。在func2
x
中,它是一个自由变量,根据您找到的语句,它被视为一个全局变量
>>> def outerfunc():
... x = 0 # x is a local
... def func1():
... global x # x is global in this scope and onwards
... def func2():
... print('func2:', x) # x is a free variable
... func2()
... print('outerfunc:', x)
... func1()
...
>>> x = 42
>>> outerfunc()
outerfunc: 0
func2: 42
>>> x = 81
>>> outerfunc()
outerfunc: 0
func2: 81