嵌套函数定义和范围(UnboundLocalError)

时间:2017-06-18 16:01:17

标签: python function variables scope

为什么以下代码无效:

def foo1(x=5):
    def bar():
        if x == 5:
            x = 6
        print(x)
    bar()

虽然此代码有效:

def foo2(x=5):
    def bar():
        if x == 5:
            print('ok')
        print(x)
    bar()

foo2()将完全符合您的预期,但foo1()会在UnboundLocalError: local variable 'x' referenced before assignment行提供if x == 5:。为什么稍后在代码中更改x的值会使此条件无效?

1 个答案:

答案 0 :(得分:3)

Python首先需要检测哪些变量是本地的,以及哪个变量是从外部范围获取的。为了做到这一点,它会查找作业,例如:

def foo1(x=5):
    def bar():
        if x == 5:
            x = 6 # an assignment, so local variable
        print(x)
    bar()

关键是,分配可以在任何地方发生。例如在最后一行。然而,从某个地方开始,x就位于本地。因此,在您的第一个代码片段中,x是一个局部变量。但是你在它被分配(有界)之前获取它,所以Python会在它上面出错。

中,您可以使用 nonlocal关键字从外部范围访问x

def foo1(x=5):
    def bar():
        nonlocal x
        if x == 5:
            x = 6
        print(x)
    bar()

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

def foo1(x=5):
    def bar():
        if bar.x == 5:
            bar.x = 6
        print(bar.x)
    bar.x = x
    bar()

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