嵌套函数定义和作用域 (UnboundLocalError)

Kah*_*nne 3 python variables scope function

为什么下面的代码无效:

def foo1(x=5):
    def bar():
        if x == 5:
            x = 6
        print(x)
    bar()
Run Code Online (Sandbox Code Playgroud)

虽然此代码有效:

def foo2(x=5):
    def bar():
        if x == 5:
            print('ok')
        print(x)
    bar()
Run Code Online (Sandbox Code Playgroud)

foo2()将会完全按照您的预期进行,但会在行处foo1()给出 a 。为什么稍后在代码中更改 x 的值会使该条件无效?UnboundLocalError: local variable 'x' referenced before assignmentif x == 5:

Wil*_*sem 5

Python 首先需要检测哪些变量是本地变量,以及哪些变量是从外部作用域获取的。为了做到这一点,它会寻找分配,例如:

def foo1(x=5):
    def bar():
        if x == 5:
            x = 6 # an assignment, so local variable
        print(x)
    bar()
Run Code Online (Sandbox Code Playgroud)

关键是,分配可以发生在任何地方。例如最后一行。尽管如此,从那一刻起,x本地某个地方就有了任务。所以在你的第一个代码片段中,x是一个局部变量。但是你在分配(有界)之前获取它,所以Python会出错。

中,您可以使用nonlocal关键字x从外部作用域进行访问:

def foo1(x=5):
    def bar():
        nonlocal x
        if x == 5:
            x = 6
        print(x)
    bar()
Run Code Online (Sandbox Code Playgroud)

对于,您可以将变量分配给 function,例如:

def foo1(x=5):
    def bar():
        if bar.x == 5:
            bar.x = 6
        print(bar.x)
    bar.x = x
    bar()
Run Code Online (Sandbox Code Playgroud)

但请注意,两者并不等同。因为在前者中,如果您更改,它也会在范围内x更改。在后一个示例中,您只需修改. 当然,如果这些是可变对象,则您可以更改同一个对象。xfoo1bar.x