首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >python和UnboundLocalError

python和UnboundLocalError
EN

Stack Overflow用户
提问于 2012-03-15 21:25:38
回答 2查看 238关注 0票数 2

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

我有一个小代码:

代码语言:javascript
复制
def foo(a):
    def bar():
        print a
    return bar()

>>>foo(5)
5

嗯,它是有效的,但是如果想要修改一个,就像这样:

代码语言:javascript
复制
def foo(a):
    def bar():
        a -= 1
    return bar()
>>>foo(5) 
UnboundLocalError: local variable 'a' referenced before assignment

所以我必须把'a‘改成另一个变量。

但我不明白这种举止。是不是因为当有赋值时,python会在locals()变量中查找,但找不到它?

谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-03-15 21:46:43

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

请参阅PEP 3104

在2.1版本之前,

对作用域的处理类似于标准C:在一个文件中只有两个作用域级别,全局和局部。在C中,这是函数定义不能嵌套的自然结果。但是在Python中,尽管函数通常是在顶层定义的,但是函数定义可以在任何地方执行。这为Python提供了没有语义的嵌套作用域的语法外观,并产生了一些程序员感到惊讶的不一致--例如,在顶层工作的递归函数在移动到另一个函数内部时将停止工作,因为递归函数本身的名称在其主体范围内将不可见。这违背了一个函数在放置在不同的上下文中时应该保持一致的直觉。下面是一个例子:

def enclosing_function():def factorial(n):如果n< 2: return 1,则返回n* factorial(n - 1) #失败,返回NameError print factorial(5)

通过使绑定在所有封闭作用域中的名称可见,Python 2.1更接近于静态嵌套作用域(参见PEP 227)。这一更改使上面的代码示例按预期工作。但是,由于对名称的任何赋值都隐式地将该名称声明为本地名称,因此不可能在外部范围内重新绑定该名称(除非全局声明强制该名称为全局名称)。因此,下面的代码旨在显示一个可以通过单击按钮来递增和递减的数字,并不像熟悉词法范围的人所期望的那样工作:

def make_scoreboard(frame,score=0):label =标签(Frame) label.pack() for i in -10,-1,1,10:定义增量(step=i):UnboundLocalError =得分+步骤#失败,返回标签‘text’=得分按钮=按钮(frame,text='%+d‘% i,command=increment) button.pack()返回标签

Python语法没有提供一种方法来指示增量中提到的名称分数是指make_scoreboard中绑定的变量分数,而不是增量中的局部变量。Python的用户和开发人员表示有兴趣消除这一限制,以便Python能够完全灵活地使用Algol风格的作用域模型,该模型现在是许多编程语言的标准,包括JavaScript、Perl、Ruby、Scheme、Smalltalk、带有GNU扩展的C和C# 2.0.

票数 8
EN

Stack Overflow用户

发布于 2012-03-15 21:45:14

Constantinius给出的理由是正确的。处理它的另一种方法(不使用全局变量)是

代码语言:javascript
复制
def foo(a):
    def bar(a):
        a -= 1
        return a
    return bar(a)
>>> print foo(5) 
4
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9720626

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档