【问题标题】:Nested function definitions and scope (UnboundLocalError)嵌套函数定义和范围 (UnboundLocalError)
【发布时间】:2017-06-18 16:01:16
【问题描述】:

为什么下面的代码无效:

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 的值会使这个条件无效?

【问题讨论】:

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

标签: python function variables scope


【解决方案1】:

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,它也会改变foo1 范围内的x。在后一个示例中,您只需修改bar.x。当然,如果这些是可变对象,您可以更改同一个对象。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-21
    • 2019-04-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多