2015-04-20 18 views
1

根據在https://docs.python.org/2/reference/simple_stmts.html#yield的文檔,Python生成器函數如何保持本地狀態?

所有局部狀態被保持,包括局部變量的當前綁定,指令指針,並且內部評價堆棧:足夠的信息被保存,以使下一次的next()被調用時,該函數可以像yield語句只是另一個外部調用一樣進行。

這裏有一個簡單的例子:

def generator(): 
    my_list = range(10) 
    print "my_list got assigned" 
    for i in my_list: 
     print i 
     yield 
    return 

在shell下,發電機()的行爲是這樣的:

>>>>generator().next() 
my_list got assigned 
0 
>>>>generator().next() 
my_list got assigned 
0 

我本來以爲my_list不會得到重新分配,每次的.next()叫做。有人可以解釋爲什麼會發生這種情況,爲什麼看起來文檔與此相矛盾?

+2

您每次創建一個新的生成器對象。在同一個對象上調用'next'兩次,你會得到你期望的輸出。 – dano

+0

幾乎重複:[Python中的生成器和for循環](http://stackoverflow.com/q/29570348/846892) –

回答

2

是,發電機維護狀態,因爲你正確文檔中找到。問題是在你的例子中,你正在創建兩個生成器。第一個未分配給任何變量,因此在.next()完成後立即丟棄。然後創建第二個生成器,它具有自己的本地狀態,從一開始就開始。

試試這個:

>>> mygen = generator() 
>>> mygen.next() 
my_list got assigned 
0 
>>> mygen.next() 
1 
5

您每次創建一個新的生成器對象。創建一個例如:

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 
1

你正在創建的generator一個新的實例,當你調用generator()。 如果您改爲

my_generator = generator() 
my_generator.next() # my_list got assigned, 0 
my_generator.next() # 1 

該列表將只被分配一次。