有人可以解释一下这段Python代码吗?

Ale*_* N. 4 python closures

我最近刚开始使用Python,并没有充分了解它的所有细节,但最近我发现这篇文章解释了为什么python有闭包,在那里,有一个示例代码如下:

y = 0

def foo():
    x = [0]
    def bar():
        print x[0], y
    def change(z):
        global y
        x[0] = y = z

    change(1)
    bar()
    change(2)
    bar()
    change(3)
    bar()
    change(4)
    bar()

foo()

1 1
2 2
3 3
Run Code Online (Sandbox Code Playgroud)

基本上我不明白它是如何工作的,在这种情况下,x [0]的构造是什么,或者实际上我理解它在做什么,我只是不知道它是怎么回事:)

Ale*_*lli 8

nonlocal在Python 3中添加关键字之前(现在仍然存在,如果2.*因为某种原因而被卡住),嵌套函数就无法重新绑定其外部函数的本地裸名称 - 因为通常是一个赋值语句barename,例如x = 23,表示x包含该语句的函数的本地名称. global存在(并且已经存在了很长时间)以允许赋值绑定或重新绑定模块级别的名字 - 但没有任何内容(除了nonlocal在Python 3中,正如我所说)允许赋值绑定或重新绑定外部函数中的名称.

解决方案当然非常简单:由于您无法绑定或重新绑定此类名称,因此请使用裸名称- 外部函数中指定的某个对象的索引或属性.当然,所述对象必须是允许重新绑定索引(例如,列表)的类型,或者允许绑定或重新绑定属性的类型(例如,函数),并且列表通常是最简单和最直接的这个方法. x正是这个代码示例中的列表 - 它只是为了让嵌套函数change重新绑定而存在x[0].


Mar*_*ers 5

如果你看一下我删除全局变量的简化代码,可能会更容易理解:

def foo():
    x = [0]
    def bar():
        print x[0]
    def change(z):
        x[0] =  z

    change(1)
    bar()

foo()
Run Code Online (Sandbox Code Playgroud)

foo中的第一行创建一个包含一个元素的列表.然后bar定义为打印第一个元素x的函数,函数change修改列表的第一个元素.当change(1)被调用时,x的值变为[1].