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

Python 嵌套函数定义和作用域(UnboundLocalError),python,function,variables,scope,python-3.x,python-2.x,Python,Function,Variables,Scope,Python 3.x,Python 2.x,为什么以下代码无效: 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()将在行中给出一个未

为什么以下代码无效:

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()
将在
行中给出一个
未绑定的局部错误:赋值前引用的局部变量“x”(如果x==5:
)。为什么稍后在代码中更改x的值会使此条件无效

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

def foo1(x=5):
    def bar():
        if x == 5:
            x = 6 # an assignment, so local variable
        print(x)
    bar()
def foo1(x=5):
    def bar():
        if bar.x == 5:
            bar.x = 6
        print(bar.x)
    bar.x = x
    bar()
例如,您可以将变量分配给函数,如:

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

但是,请注意,这两个值不相等。因为在前者中,如果您更改
x
,也将更改
foo1
范围中的
x
。在后一个示例中,您仅修改
bar.x
。当然,如果这些对象是可变的,您可以更改相同的对象。

Python首先在代码中查找赋值操作。从发生的那一刻起,它就被认为是一个局部变量,这确实是一个(不是很优雅的)结果。这是否回答了你的问题?