Python: 在外部函数 return 之后修改非局部变量
Python: modify nonlocal variable after return from outer function
考虑以下示例:
def g():
in_g=100
def f1():
nonlocal in_g
in_g = 10
def f2():
nonlocal in_g
print(in_g)
return (f1,f2)
(f1, f2) = g()
f2() #prints 100
f1()
f2() #prints 10
内部函数 f1
和 f2
在它们的 "closures" 中都可以访问变量 in_g
。
但是,g
returns之后,in_g
在内存中保存在哪里呢?
我假设当 g
正在执行时,in_g
是堆栈帧上的一个变量,对应于对 g
的调用。因此,g
、f1
和 f2
在使用变量 in_g
.
时都访问相同的内存位置(在堆栈上)
但是,如示例所示,在 g
returns 之后,f1
和 f2
在引用 in_g
时仍然访问相同的内存位置。然而,现在 g
返回了,那个内存位置不能再在栈上了。
以上代码的输出是 100 & 10 。
因为首先 f2() 调用所以它直接访问 in_g 变量并打印它的值。在 f1() 调用之后它将 in_g 变量值更新为 10。然后 f2( ) 函数再次调用,因此由于非本地语句,它绑定了先前的值,这就是它打印 10 值的原因。
nonlocal 语句 导致列出的标识符引用最近封闭范围内的先前绑定变量,不包括全局变量。这很重要,因为绑定的默认行为是首先搜索本地命名空间。该语句允许封装的代码重新绑定除全局(模块)范围之外的局部范围之外的变量。
与全局语句中列出的名称不同,非局部语句中列出的名称必须引用封闭范围中预先存在的绑定(无法明确确定应在其中创建新绑定的范围)。
非本地语句中列出的名称不得与本地范围内预先存在的绑定冲突。
我相信我在这里找到了答案:http://stupidpythonideas.blogspot.ro/2015/12/how-lookup-works.html。
因此,当访问 in_g
、g
、f1
和 f2
时,会访问一个 cell variable
,后者又持有对实际对象的引用目的。
考虑以下示例:
def g():
in_g=100
def f1():
nonlocal in_g
in_g = 10
def f2():
nonlocal in_g
print(in_g)
return (f1,f2)
(f1, f2) = g()
f2() #prints 100
f1()
f2() #prints 10
内部函数 f1
和 f2
在它们的 "closures" 中都可以访问变量 in_g
。
但是,g
returns之后,in_g
在内存中保存在哪里呢?
我假设当 g
正在执行时,in_g
是堆栈帧上的一个变量,对应于对 g
的调用。因此,g
、f1
和 f2
在使用变量 in_g
.
但是,如示例所示,在 g
returns 之后,f1
和 f2
在引用 in_g
时仍然访问相同的内存位置。然而,现在 g
返回了,那个内存位置不能再在栈上了。
以上代码的输出是 100 & 10 。
因为首先 f2() 调用所以它直接访问 in_g 变量并打印它的值。在 f1() 调用之后它将 in_g 变量值更新为 10。然后 f2( ) 函数再次调用,因此由于非本地语句,它绑定了先前的值,这就是它打印 10 值的原因。
nonlocal 语句 导致列出的标识符引用最近封闭范围内的先前绑定变量,不包括全局变量。这很重要,因为绑定的默认行为是首先搜索本地命名空间。该语句允许封装的代码重新绑定除全局(模块)范围之外的局部范围之外的变量。 与全局语句中列出的名称不同,非局部语句中列出的名称必须引用封闭范围中预先存在的绑定(无法明确确定应在其中创建新绑定的范围)。 非本地语句中列出的名称不得与本地范围内预先存在的绑定冲突。
我相信我在这里找到了答案:http://stupidpythonideas.blogspot.ro/2015/12/how-lookup-works.html。
因此,当访问 in_g
、g
、f1
和 f2
时,会访问一个 cell variable
,后者又持有对实际对象的引用目的。