关于范围:Python局部变量表现奇怪

Python local variables behaving strangely

本问题已经有最佳答案,请猛点这里访问。

考虑以下代码:

1
2
3
4
5
6
7
8
9
10
def g():
    a = {}
    b = 0
    def f():
        a[0] = b
    f()
    print(a)
    return a
a = g()
print(a)

它在执行时提供以下输出:

1
2
{0: 0}
{0: 0}

但如果我尝试更新EDOCX1中的b,就像

1
2
3
4
5
6
7
8
9
10
11
def g():
    a = {}
    b = 0
    def f():
        a[0] = b
        b+=1
    f()
    print(a)
    return a
a = g()
print(a)

它引发以下错误:

1
UnboundLocalError: local variable 'b' referenced before assignment

这是预期的吗?我需要在f()中更新b。这不可能吗?


显式地将ab传递给您的函数。

1
2
3
4
5
6
7
8
9
def g():
    a = {}
    b = 0
    def f(a, b):
        a[0] = b
        b += 1
        return b
    b = f(a, b)
    return a

您需要使用nonlocal关键字:

1
2
3
4
5
6
7
8
9
10
11
12
def g():
    a = {}
    b = 0
    def f():
        nonlocal b
        a[0] = b
        b+=1
    f()
    print(a)
    return a
a = g()
print(a)

这是因为b += 1等于b = b + 1,所以在函数f()的内部分配b。即使在代码的后面,这将使它成为整个f()函数的局部变量,因此a[0] = b将引用尚未定义的局部b。使用nonlocal可以告诉解释器已经有了一个变量b,应该在函数中使用它,而不是创建一个新的局部变量。