python 3.x 中的闭包和变量范围问题让我感到困惑

Closure and variable scope in python 3.x issue causing me confusion

我正在使用 Python 3.7.0,我正在做一些实验以理解变量范围的微妙之处,但我仍然不理解这种行为。

当我执行这段代码时:

def f():
    x=0
    def g():y=x+1;x=y
    return g
f()()

我得到 UnboundLocalError: 局部变量 'x' 在赋值前被引用

但是当我执行这个时:

def f():
   x=0
   def g():y=x+1
   return g
f()()

它工作正常。甚至这个:

def f():
   x=0
   def g():x=1
   return g
f()()

它也很好用。所以我很困惑。在我看来,如果将值 1 分配给 g 函数中的非局部变量 x 单独工作正常,另一方面,如果将包含 x 的表达式分配给函数 g 中的局部变量 y 也可以正常工作,那么指令 y=x+1x=y 应该都可以工作。我不明白是什么导致了错误。我觉得我在理解 Python 的行为时遗漏了一些基本的东西。

我会采取不明智的做法。在以下代码中:

def f():
    x = 0  # assignment makes this x local to f()

    def g():
        y = x + 1
        x = y  # assignment makes this x local to g()

    return g

f()()

g()x 的赋值强制它成为 g() 的局部变量。因此,当您访问未分配的本地值时,第一行会导致错误。我相信这个 "assignment makes it local" 逻辑不遵循您的程序流程——函数被视为一个整体来做出这个决定,然后逐行查看代码。

您可以从函数访问范围内的任何变量,但只能设置局部变量。除非您已将要分配的变量声明为 globalnonlocal:

def f():
    x = 0  # assignment makes this x local to f()

    def g():
        nonlocal x

        y = x + 1
        x = y  # x is declared to come from a nonlocal scope

    return g

f()()

在你的第二个例子中,这不是问题,因为你只查看 x 的值,而不是设置它,因此它可以来自任何适当的范围:

def f():
    x = 0  # assignment makes this x local to f()

    def g():
        y = x + 1  # x comes from an outer scope

    return g

f()()

最后,您的第三个示例与第一个示例相同,没有无符号局部变量使用错误:

def f():
    x = 0  # assignment makes this x local to f()

    def g():
        x = 1  # assignment makes this x local to g()

    return g

f()()

It seems to me that if assigning the value 1 to the nonlocal variable x in the g function works fine alone

您如何确定 f()x 的重新分配工作正常?