一个函数返回另一个函数为什么里面的函数可以限定父级列表而不是常量的范围?

问题描述

考虑此功能

def g():
    x = []
    
    def f():
        x.append([0])
        print(x)
        pass
    return f

调用

test = g()
test()

我得到以下输出

Out: [[0]]

我们可以重新初始化测试函数并多次调用

test = g()
for i in range(3):
    test()

产生以下输出

Out: [[0]]
[[0],[0]]
[[0],[0],[0]]

但是,定义以下功能

def j():
    x = 1
    def f():
        x += 1
        print(x)
        pass
    return f

调用它:

test = j()
test()

导致错误

UnboundLocalError: local variable 'x' referenced before assignment

列表似乎在内部函数作用域中,而值不在。为什么会这样?

解决方法

这是因为j使用赋值表达式,其中g使用方法调用。请记住,x += 1等效于x = x + 1。如果您将g更改为:

def g():
    x = []

    def f():
        x += [[0]]
        print(x)
        pass
    return f

您得到:

>>> test = g()
>>> test()
Traceback (most recent call last):
  File "<pyshell#20>",line 1,in <module>
    test()
  File "<pyshell#18>",line 5,in f
    x += [[0]]
UnboundLocalError: local variable 'x' referenced before assignment
,

@rassar清楚地解释了原因。在这里,我给出一个解决方案:

def j():
    x = 1
    def f():
        nonlocal x
        x += 1
        print(x)
        pass
    return f

实际上,这不是一个简单的问题。即使+=看起来像是一个有界方法调用,还是一个就地操作(如果您有其他语言的经验)。但是运行的是类似x = x.__add__(1)x = x.__iadd__(1)的东西。这是一项任务。

,

因为,python编译器知道函数f中的变量'x'是局部变量,而不是函数j中的局部变量。因此发生了您上面提到的错误。

因此,您应该使用非本地。请参考下面的链接。 Accessing parent function's variable in a child function called in the parent using python

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...