Python生成器函数如何维护本地状态?

Bow*_*ser 2 python generator subroutine

根据https://docs.python.org/2/reference/simple_stmts.html#yield上的文档,

保留所有本地状态,包括局部变量,指令指针和内部评估堆栈的当前绑定:保存足够的信息,以便下次调用next()时,函数可以像yield语句一样完成只是另一个外部电话.

这是一个简单的案例:

def generator():
    my_list = range(10)
    print "my_list got assigned"
    for i in my_list:
        print i
        yield
    return
Run Code Online (Sandbox Code Playgroud)

在shell中,generator()的行为如下:

>>>>generator().next()
my_list got assigned
0
>>>>generator().next()
my_list got assigned
0
Run Code Online (Sandbox Code Playgroud)

我原以为每次调用my_list都不会被重新分配.next()被调用.有人可以解释为什么会发生这种情况,以及为什么文档似乎与此相矛盾?

Mar*_*ers 6

您每次都在创建一个新的生成器对象.创建一个实例:

g = generator()
g.next()
g.next()
Run Code Online (Sandbox Code Playgroud)

这里g引用维护状态的生成器对象:

>>> def generator():
...     my_list = range(10)
...     print "my_list got assigned"
...     for i in my_list:
...         print i
...         yield
...     return
... 
>>> g = generator()
>>> g
<generator object generator at 0x100633f50>
>>> g.next()
my_list got assigned
0
>>> g.next()
1
Run Code Online (Sandbox Code Playgroud)


Phi*_*lip 5

是的,生成器会维护状态,正如您在文档中正确找到的那样。问题是在您的示例中,您正在创建两个生成器。第一个没有分配给任何变量,因此它在.next()完成后立即被丢弃。然后,您创建第二个生成器,它具有自己的本地状态,从头开始。

尝试这个:

>>> mygen = generator()
>>> mygen.next()
my_list got assigned
0
>>> mygen.next()
1
Run Code Online (Sandbox Code Playgroud)