嵌套函数定义和范围(UnboundLocalError) [英] Nested function definitions and scope (UnboundLocalError)

查看:72
本文介绍了嵌套函数定义和范围(UnboundLocalError)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么以下代码无效:

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()将在行if x == 5:处给出UnboundLocalError: local variable 'x' referenced before assignment.为什么稍后在代码中更改x的值会使此条件无效?

foo2() will do exactly what you expect, but foo1() will give a UnboundLocalError: local variable 'x' referenced before assignment at the line if x == 5:. Why does altering the value of x later on in the code make this conditional invalid?

推荐答案

Python首先需要检测哪些变量是本地变量,以及哪些变量是从外部范围获取的.为此,它会查找作业,例如:

Python needs first to detect what variables are local, and which variable are fetched from an outer scope. In order to do that it looks for assignments, like:

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

重点是,作业可以在任何地方发生.例如在最后一行.但是,从x本地开始就存在分配.因此,在您的第一个代码片段中,x是局部变量.但是您在分配它(绑定)之前先获取它,所以Python会在上面出错.

The point is, that the assignment can happen anywhere. For instance on the last line. Nevertheless, from the moment there is an assignment somewhere x is local. So in your first code fragment, x is a local variable. But you fetch it before it is assigned (bounded), so Python will error on it.

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

In python-3.x you can use the nonlocal keyword to access x from an outer scope:

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

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

For python-2.x, you can for instance assign the variable to the function, like:

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.当然,如果这些是可变对象,则可以更改同一对象.

Note however that the two are not equivalent. Since in the former if you alter x, it will be alter the x in the foo1 scope as well. In the latter example you only modify bar.x. Of course if these are mutable objects, you alter the same object.

这篇关于嵌套函数定义和范围(UnboundLocalError)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆