【问题标题】:Python: modify nonlocal variable after return from outer functionPython:从外部函数返回后修改非局部变量
【发布时间】:2018-06-23 04:54:37
【问题描述】:

考虑以下示例:

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

内部函数f1f2 在它们的“闭包”中都可以访问变量in_g。 但是g返回后,in_g在内存中保存在哪里?

我假设当g 正在执行时,in_g 是堆栈帧上的一个变量,对应于对g 的调用。因此,gf1f2 在使用变量in_g 时都访问相同的内存位置(在堆栈上)。

但是,如示例中所示,在 g 返回后,f1f2 在引用 in_g 时仍然访问相同的内存位置。但是,既然g 返回了,那个内存位置就不能再在堆栈上了。

【问题讨论】:

    标签: python closures python-nonlocal


    【解决方案1】:

    上述代码的输出是 100 & 10 。


    因为第一个 f2() 调用,所以它直接访问 in_g 变量并打印它的值。在 f1() 调用之后,它将 in_g 变量值更新为 10。然后 f2() 函数再次调用,因为 nonlocal 语句它绑定了先前的值,这就是它打印 10 值的原因。


    nonlocal 语句 导致列出的标识符引用之前在最近的封闭范围内绑定的变量,不包括全局变量。这很重要,因为绑定的默认行为是首先搜索本地命名空间。该语句允许封装代码重新绑定全局(模块)范围之外的局部范围之外的变量。 与 global 语句中列出的名称不同,在 nonlocal 语句中列出的名称必须引用封闭范围中的预先存在的绑定(无法明确确定应创建新绑定的范围)。 非本地语句中列出的名称不得与本地范围内的预先存在的绑定发生冲突。


    【讨论】:

    • 是的,我知道这一点,但是在g 返回后存储的变量in_g 在内存中的哪个位置?
    • 它存储在一个内存段中,直到程序没有终止。
    【解决方案2】:

    我相信我在这里找到了答案:http://stupidpythonideas.blogspot.ro/2015/12/how-lookup-works.html

    因此,当访问 in_ggf1f2 时,访问一个 cell variable,它又持有对实际对象的引用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-08-11
      • 2018-09-23
      • 1970-01-01
      • 2022-11-10
      • 2011-04-15
      • 1970-01-01
      • 2023-03-27
      • 2023-03-23
      相关资源
      最近更新 更多