python和UnboundLocalError

python和UnboundLocalError,python,Python,我对局部变量和python(2.7)有点问题 我有一个小代码: def foo(a): def bar(): print a return bar() >>>foo(5) 5 好的,它正在工作,但如果要修改a,如下所示: def foo(a): def bar(): a -= 1 return bar() >>>foo(5) UnboundLocalError: local variable

我对局部变量和python(2.7)有点问题

我有一个小代码:

def foo(a):
    def bar():
        print a
    return bar()

>>>foo(5)
5
好的,它正在工作,但如果要修改a,如下所示:

def foo(a):
    def bar():
        a -= 1
    return bar()
>>>foo(5) 
UnboundLocalError: local variable 'a' referenced before assignment
因此,我必须将“a”影响到另一个变量

但我不明白这种行为。 是因为当有赋值时,python查找locals()变量却没有找到它吗


谢谢。

康斯坦丁尼乌斯给出的理由是正确的。另一种处理方法(不使用全局变量)是


您发现了Python中曾经存在的问题!简而言之,在Python2.x中不能这样做(尽管可以),但在3.x中可以使用
nonlocal
关键字

见:

在版本2.1之前,Python对作用域的处理类似于 标准C:在一个文件中只有两个级别的作用域,即全局作用域 而且是本地的。在C中,这是以下事实的自然结果: 函数定义不能嵌套。但是在Python中,虽然函数 通常在顶层定义,函数定义可以 在任何地方执行。这使Python具有嵌套的语法外观 没有语义的范围界定,并且产生了 令一些程序员惊讶的是——例如,递归函数 在高层工作的人在搬进去后会停止工作 另一个函数,因为递归函数本身的名称不会 在其主体范围内不再可见。这违背了直觉 函数在不同位置时应保持一致的行为 上下文。下面是一个例子:

def enclosing_function():
    def factorial(n):
        if n < 2:
            return 1
        return n * factorial(n - 1)  # fails with NameError
    print factorial(5)
Python语法没有提供一种方法来指示名称得分 增量中提到的是指在 制作记分板,而不是增量中的局部变量。用户和 Python的开发人员表示有兴趣删除此选项 限制,使Python能够具有 Algol风格的作用域模型,现在在许多编程中是标准的 语言,包括JavaScript、Perl、Ruby、Scheme、Smalltalk、C和 GNU扩展和C#2.0


为什么在第二个示例中调用
bar()
内部的
bar()
?它必须以
RuntimeError停止:一旦您通过赋值行,就超过了最大递归深度。|在第二个示例中,您在bar()中返回bar(),这是您想要的还是缩进/复制错误?因为你在第一个例子中没有
def enclosing_function():
    def factorial(n):
        if n < 2:
            return 1
        return n * factorial(n - 1)  # fails with NameError
    print factorial(5)
def make_scoreboard(frame, score=0):
    label = Label(frame)
    label.pack()
    for i in [-10, -1, 1, 10]:
        def increment(step=i):
            score = score + step  # fails with UnboundLocalError
            label['text'] = score
        button = Button(frame, text='%+d' % i, command=increment)
        button.pack()
    return label