Python的闭包 - 在赋值之前引用的局部变量

den*_*iss 8 python

我试图理解封闭如何在Python中工作.

我觉得add1应该在这里工作得很好.我希望在调用x时定义变量helper.但是,它给了我一个Local variable referenced before assignment错误.

add2非常相似add1.它不是用整数赋值x,而是用字典赋值.它的行为也符合我的预期.x是内部定义和引用的helper.

import random

def add1():
    x = 0
    def helper():
        x = x + 1
        return x
    return helper

def add2():
    x = {}
    def helper():
        x[random.randint(1,1000)] = 3
        return x
    return helper

if __name__ == '__main__':
    a1 = add1()
    a2 = add2()

    # print(a1()) #This causes error
    print(a2()) #{650: 3}
    print(a2()) #{650: 3, 333: 3}
Run Code Online (Sandbox Code Playgroud)

这背后的逻辑是什么?除了那些不同的类型之外,我在做什么x

Ign*_*ams 16

您期望编译器知道变量已绑定在闭包之外.事实并非如此,因此您需要使用它nonlocal来表明这一点.

def add1():
    x = 0
    def helper():
        nonlocal x
        x = x + 1
        return x
    return helper
Run Code Online (Sandbox Code Playgroud)

由丹尼斯编辑:

nonlocal没有必要,add2因为它只是修改x而不是重新绑定它(也就是说不重新分配它).而在add1,x= x+1是,是re-assignment.

  • 另请注意,如果您已将 `x + 1` 分配给一个新引用,例如 `y`,则不需要 `nonlocal`。然后解释器会在周围的作用域中查找 `x`。当您重新绑定相同的引用时,它假定您正在谈论一个局部变量并且在局部范围内找不到它。 (2认同)