简体   繁体   English

python 3.x 中的闭包和变量 scope 问题导致我感到困惑

[英]Closure and variable scope in python 3.x issue causing me confusion

I am using Python 3.7.0 and I am doing some experiments in order to comprehend the subtleties of variable scopes but I still don't understand this behaviour.我正在使用 Python 3.7.0 并且我正在做一些实验以理解变量范围的微妙之处,但我仍然不理解这种行为。

When I execute this code:当我执行此代码时:

def f():
    x=0
    def g():y=x+1;x=y
    return g
f()()

I get UnboundLocalError: local variable 'x' referenced before assignment我得到 UnboundLocalError: local variable 'x' referenced before assignment

However when I execute this one:但是,当我执行这个时:

def f():
   x=0
   def g():y=x+1
   return g
f()()

It works fine.它工作正常。 And even this one:甚至这个:

def f():
   x=0
   def g():x=1
   return g
f()()

It also works fine.它也可以正常工作。 So I am confused.所以我很困惑。 It seems to me that if assigning the value 1 to the nonlocal variable x in the g function works fine alone and on the other hand if assigning an expression containing x to a local variable y in the function g works also fine then the instructions y=x+1 and x=y should both work.在我看来,如果将值1分配给g function 中的非局部变量x单独工作正常,另一方面,如果将包含x的表达式分配给 function g中的局部变量y也可以正常工作,那么指令y=x+1x=y都应该工作。 I don't understand what is causing the error.我不明白是什么导致了错误。 I feel I am missing something fundamental in my understanding of Python's behaviour.我觉得我在理解 Python 的行为时缺少一些基本的东西。

I'll take an ill-advised crack at this.我会对此采取不明智的做法。 In the following code:在以下代码中:

def f():
    x = 0  # assignment makes this x local to f()

    def g():
        y = x + 1
        x = y  # assignment makes this x local to g()

    return g

f()()

The assignment of x inside g() forces it to be a variable local to g() . xg()中的赋值强制它成为g()的局部变量。 So the first line causes the error as you accessing the value of an unassigned local.因此,当您访问未分配的本地值时,第一行会导致错误。 I believe this "assignment makes it local" logic doesn't follow the flow of your program -- the function is viewed as whole to make this determination and then the code is looked at line by line.我相信这种“赋值使其成为本地”逻辑不符合您的程序流程——function 被视为整体以做出此决定,然后逐行查看代码。

You can access any variable in scope from a function, but you can only set locals.您可以从 function 访问 scope 中的任何变量,但您只能设置局部变量。 Unless you've declared the variable you're assigning as global or nonlocal :除非您已将要分配的变量声明为globalnonlocal

def f():
    x = 0  # assignment makes this x local to f()

    def g():
        nonlocal x

        y = x + 1
        x = y  # x is declared to come from a nonlocal scope

    return g

f()()

In your second example, it's not an issue as you're only looking at the value of x , not setting it, so it can come from any appropriate scope:在您的第二个示例中,这不是问题,因为您只查看x的值,而不是设置它,因此它可以来自任何适当的 scope:

def f():
    x = 0  # assignment makes this x local to f()

    def g():
        y = x + 1  # x comes from an outer scope

    return g

f()()

Finally, your third example is the same as the first without the unssigned local variable usage error:最后,您的第三个示例与第一个示例相同,没有未分配的局部变量使用错误:

def f():
    x = 0  # assignment makes this x local to f()

    def g():
        x = 1  # assignment makes this x local to g()

    return g

f()()

It seems to me that if assigning the value 1 to the nonlocal variable x in the g function works fine alone在我看来,如果将值 1 分配给 g function 中的非局部变量 x 单独工作正常

How did you determine that the reassignment of x in f() worked fine?您如何确定在f()中重新分配x工作正常?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM