Python 生成器函数如何维护本地状态?
How do Python generator functions maintain local state?
根据 https://docs.python.org/2/reference/simple_stmts.html#yield、
的文档
all local state is retained, including the current bindings of local variables, the instruction pointer, and the internal evaluation stack: enough information is saved so that the next time next() is invoked, the function can proceed exactly as if the yield statement were just another external call.
这是一个简单的例子:
def generator():
my_list = range(10)
print "my_list got assigned"
for i in my_list:
print i
yield
return
在 shell 中,generator() 的行为如下:
>>>>generator().next()
my_list got assigned
0
>>>>generator().next()
my_list got assigned
0
我原以为 my_list 不会在每次调用 .next() 时都被重新分配。有人可以解释为什么会发生这种情况,以及为什么文档似乎与此相矛盾吗?
您每次都在创建一个新的生成器对象。创建一个实例:
g = generator()
g.next()
g.next()
这里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
是的,生成器保持状态,正如您在文档中正确找到的那样。问题是在您的示例中,您正在创建两个生成器。第一个没有分配给任何变量,所以它在 .next()
完成后立即被丢弃。然后你创建第二个生成器,它有自己的本地状态,从头开始。
试试这个:
>>> mygen = generator()
>>> mygen.next()
my_list got assigned
0
>>> mygen.next()
1
当您调用 generator()
时,您正在创建 generator
的新实例。
如果你改为
my_generator = generator()
my_generator.next() # my_list got assigned, 0
my_generator.next() # 1
列表只会分配一次。
根据 https://docs.python.org/2/reference/simple_stmts.html#yield、
的文档all local state is retained, including the current bindings of local variables, the instruction pointer, and the internal evaluation stack: enough information is saved so that the next time next() is invoked, the function can proceed exactly as if the yield statement were just another external call.
这是一个简单的例子:
def generator():
my_list = range(10)
print "my_list got assigned"
for i in my_list:
print i
yield
return
在 shell 中,generator() 的行为如下:
>>>>generator().next()
my_list got assigned
0
>>>>generator().next()
my_list got assigned
0
我原以为 my_list 不会在每次调用 .next() 时都被重新分配。有人可以解释为什么会发生这种情况,以及为什么文档似乎与此相矛盾吗?
您每次都在创建一个新的生成器对象。创建一个实例:
g = generator()
g.next()
g.next()
这里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
是的,生成器保持状态,正如您在文档中正确找到的那样。问题是在您的示例中,您正在创建两个生成器。第一个没有分配给任何变量,所以它在 .next()
完成后立即被丢弃。然后你创建第二个生成器,它有自己的本地状态,从头开始。
试试这个:
>>> mygen = generator()
>>> mygen.next()
my_list got assigned
0
>>> mygen.next()
1
当您调用 generator()
时,您正在创建 generator
的新实例。
如果你改为
my_generator = generator()
my_generator.next() # my_list got assigned, 0
my_generator.next() # 1
列表只会分配一次。