Python闭包能否存储和更改外部标量?

2024-06-24 13:14:13 发布

您现在位置:Python中文网/ 问答频道 /正文

环境:Python 3.7.5

我试图理解Python中的闭包,因此我做了以下尝试:

首先,我编写了一个函数,生成函数来更改我启动的向量:

def outer(c=[0,0]):
    
    def inner(x):
        nx = c[0] + x[0]
        ny = c[1] + x[1]
        c[0] = nx
        c[1] = ny
        return c
    
    return inner

以下是我得到的结果:

>>> p = outer()
>>> p([1,2])
[1, 2]
>>> p([1,2])
[2, 4]
>>> p([1,2])
[3, 6]

它工作得很好,内部函数每一步都存储向量,以便向量可以逐渐变化

然后,我编写了一个类似的函数,只将向量c更改为标量:

def outer(c=0):
    
    def inner(x):
        nx = c + x
        c = nx
        return c
    
    return inner

但是,这次我无法运行它:

>>> p = outer()
>>> p(1)
Traceback (most recent call last):
  File "<pyshell#35>", line 1, in <module>
    p(1)
  File "C:/Users/thisi/Desktop/21345.py", line 5, in inner
    nx = c + x
UnboundLocalError: local variable 'c' referenced before assignment

我想知道为什么python这次找不到变量“c”?为什么第一个案例有效


Tags: 函数inmostreturn环境defline向量
2条回答

使用nonlocal c以达到预期效果。第一种情况之所以有效,是因为您不直接更改c,而是将c的内容指定给list类型的内容

def outer(c=0):

    def inner(x):
        nonlocal c   # <  note `nonlocal`
        nx = c + x
        c = nx
        return c

    return inner

p = outer()
print( p(1) )
print( p(1) )

印刷品:

1
2

如果函数中有任何变量赋值语句,则该变量位于函数的局部范围内(如果未显式声明nonlocal

考虑此代码:

def outer(c=0):
    
    def inner(x):
        if False: c = 0
        return c + x
    
    return inner

func = outer(3)
print(func(2))

这将给出一个UnboundLocalError,即使赋值c = 0从未执行。但是如果带有赋值的行被完全删除,那么它将运行

在列表示例中,变量c未分配到inner中的任何位置;仅使用项目分配对其进行修改

相关问题 更多 >