Python closures

你。 提交于 2019-12-08 05:22:31

问题


def counter(x):

    def _cnt():
        #nonlocal x
        x = x+1
        print(x)
        return x

    return _cnt
a = counter(0)
print(a())

Above code gives the following error

UnboundLocalError: local variable 'x' referenced before assignment

Why this is not able to create a new object with value 'x+1' in the namespace of _cnt and bind it to x. we will have reference x in both function namespaces


回答1:


As soon as you assign to a name in a given scope, all references to the same name inside the same scope are local. Hence x + 1 cannot be evaluated (as it tries to reference the local x).

Hence this works:

def f():
    x = 42
    def g():
        print(x)
    g()
f()

But this doesn't:

def f():
    x = 42
    def g():
        print(x)
        x = 42
    g()
f()

The first print has this bytecode:

0 LOAD_GLOBAL              0 (print) 
3 LOAD_DEREF               0 (x) 
6 CALL_FUNCTION            1 
9 POP_TOP  

while the second print has this one:

0 LOAD_GLOBAL              0 (print) 
3 LOAD_FAST                0 (x) 
6 CALL_FUNCTION            1 
9 POP_TOP 



回答2:


The scopes of function counter and _cnt are not the same. Even though they're nested, it doesn't matter.

So the x in counter does not exist in _cnt. Perhaps pass it as an argument (or use nonlocal, as you seemed to have understood)



来源:https://stackoverflow.com/questions/19063648/python-closures

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!