2015-11-02 76 views
1

我想創建一個具有類似生成器的方法的類。我對發電機相當陌生。這裏是我的代碼:類中的python生成器

class MyGen: 

    def __init__(self): 
     self.a = 0 

    def create_generator(self): 
     yield self.a 
     self.a += 1 

if __name__ == "__main__": 
    myGenInstance = MyGen() 
    myGen = myGenInstance.create_generator() 
    for i in range(3): 
     print(next(myGen)) 

我得到這個錯誤:

Traceback (most recent call last): 
0 
File "C:/Users/tvavr/PycharmProjects/filter/geneŕator_test.py", line 17, in <module> 
print(next(myGen)) 
StopIteration 
Process finished with exit code 1 

我缺少什麼?

+4

您的生成器只返回一個值(它只是一個不在任何循環內的yield語句)。試圖正確地獲得另一個值會導致「StopIteration」異常,表示沒有更多的值可以產生。 –

+0

這是非常值得的時間來閱讀:http://stackoverflow.com/a/231855/1832539 – idjaw

+0

換句話說:你不會錯過任何東西,它的行爲完全如預期。 – jonrsharpe

回答

0

讀取代碼時,沒有錯誤,python引發的異常是正常行爲。

create_generator方法只能產生一個值,因爲只使用了一個產量。

認爲:

class Mygen: 
    def __init__(self): 
     self.a = 0 

    def create_generator(self): 
     yield self.a 
     self.a += 1 

     yield self.a 
     self.a += 1 

     yield self.a 

當你運行如下注意到發生了什麼代碼:

if __name__ == "__main__": 
my_gen_instance = MyGen() 
my_gen = my_gen_instance.create_generator() 
for i in range(3): 
    print('the value number', i, 'is:', next(myGen)) 

輸出將是:

the value number 0 is 0 
the value number 1 is 1 
the value number 2 is 2 

現在,如果我們改變範圍從3到4,看看會發生什麼:

if __name__ == "__main__": 
    my_gen_instance = MyGen() 
    my_gen = my_gen_instance.create_generator() 
    for i in range(4): 
     print('the value number', i, 'is:', next(myGen)) 

輸出將是:

the value number 0 is 0 
the value number 1 is 1 
the value number 2 is 2 
Traceback (most recent call last): 
    File "pygen.py", line 21, in <module> 
    print('the value number', i, 'is', next(my_gen)) 
StopIteration 

因爲發電機是特殊類型的迭代器,他們拋出一個StopIteration時,他們都用盡像正常的迭代器

因此,爲了避免這種情況你必須預見到這種行爲其中,因爲你需要儘可能多的收益,最好的方式是如下創建MyGen類中無限發生器:

class MyGen: 
    def __init__(self): 
     self.a = 0 

    def create_generator(self): 
     while True: 
      yield self.a 
      self.a += 1 

現在,您可以根據需要對通過此方法創建的生成器進行迭代。