提问人:saveturn 提问时间:10/5/2018 最后编辑:Martijn Pieterssaveturn 更新时间:10/5/2018 访问量:152
在 Python 中被视为全局变量的自由变量?
Free variables treated as globals in Python?
问:
在 Python 3.7 参考手册的执行模型部分,我阅读了以下语句:
该语句的作用域与同一块中的名称绑定操作相同。如果 free 变量的最近封闭范围包含语句,则将 free 变量视为全局变量。
global
global
因此,我在 Python 解释器中键入了以下代码:
x =0
def func1():
global x
def func2():
x = 1
func2()
调用后,我本来希望全局范围内的值更改为 .func1()
x
1
我做错了什么?
答:
x = 1
in 不是自由变量。这只是另一个当地人;你绑定到名称,绑定到的名称默认是本地人,除非你告诉 Python 另有说明。func2
从相同的执行模型文档中:
如果名称绑定在块中,则它是该块的局部变量,除非声明为 或 。[...] 如果变量在代码块中使用但未在代码块中定义,则该变量是自由变量。
nonlocal
global
(粗体强调我的)
你用 绑定了块中的名称,所以它是该块中的局部变量,不能是自由变量。所以你找到的部分不适用,因为这只适用于自由变量:x = 1
如果 free 变量的最近封闭范围包含语句,则将 free 变量视为全局变量。
global
不应绑定 ,因为只有作用域中未绑定的名称才是自由变量。x
func2()
所以这有效:
>>> def func1():
... global x
... x = 1
... def func2():
... print(x) # x is a free variable here
... func2()
...
>>> func1()
1
>>> x
1
x
in 现在是一个自由变量;它未在 的作用域中定义,因此从父作用域中选取它。这里的父作用域是 ,但在那里标记为全局,因此在读取函数时使用全局值。func2
func2
func1
x
x
print()
与此形成鲜明对比的是,在以下情况下未被标记为全局: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
此处的全局名称设置为 ,但这不会影响打印的内容。 in 是一个自由变量,但父作用域仅具有本地名称。x
42
x
func2
func1
x
当您添加一个新的最外层范围时,它变得更加有趣,其中仍然是本地的: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
x
in 是绑定的,所以不是自由变量。因此,它是该范围内的本地。但是,在 中,声明在嵌套的 scrope 中标记为全局。In 是一个自由变量,根据您找到的语句,它被视为全局变量。outerfunc
func1
global x
x
func2
x
评论