2016-08-10 7 views
2

関数ジェネレータとクラスジェネレータの動作が異なるのはなぜですか?つまり、クラスジェネレータでは、何度でもジェネレータを使用できますが、関数ジェネレータでは一度しか使用できません。なぜそうなのか? f_gen()関数を呼び出す関数ジェネレータとPython 3のクラスジェネレータ

def f_counter(low,high): 
    counter=low 
    while counter<=high: 
     yield counter 
     counter+=1 

class CCounter(object): 
    def __init__(self, low, high): 
     self.low = low 
     self.high = high 
    def __iter__(self): 
     counter = self.low 
     while self.high >= counter: 
      yield counter 
      counter += 1 

f_gen=f_counter(5,10) 
for i in f_gen: 
    print(i,end=' ') 

print('\n') 

for j in f_gen: 
    print(j,end=' ') #no output 

print('\n') 

c_gen=CCounter(5,10) 
for i in c_gen: 
    print(i,end=' ') 

print('\n') 

for j in c_gen: 
    print(j,end=' ') 

答えて

4

generator iterator、具体)iterator生成します。イテレータは一度だけループすることができます。あなたのクラスはで、ではなく、iterableです。イテレーターの任意の数を生成できるオブジェクトです。 forが順番にあなたの実装では、それぞれの時間を新しいジェネレータイテレータを返すobject.__iter__()を呼び出し、あなたが渡すオブジェクト、上のiter() functionを適用するため

は、あなたのクラスは、あなたがforを使用するたびに新しいジェネレータイテレータを生成しますいわゆる。

c_gen = CCounter(5,10) 
c_gen_iterator = iter(c_gen) 
for i in c_gen_iterator: 
    # ... 

あなたはまた、__iter__からselfを返すことによってイテレータCCounter()を作ることができ、そして:つまり、

、あなたはループの前iter(instance)またはinstance.__iter__()を呼び出すことにより、クラスが同じように動作することができますobject.__next__() method(パイソン2でobject.next())を追加:

class CCounter(object): 
    def __init__(self, low, high): 
     self.low = low 
     self.high = high 
    def __iter__(self): 
     return self 
    def __next__(self): 
     result = self.low 
     if result >= self.high: 
      raise StopIteration() 
     self.low += 1 
     return result 
2

あなたのクラスはiterablですeではなく、イテレータ自体ではありません。 iterを呼び出すたびに、新しいイテレータが取得されます。

あなたはクラスでジェネレータ関数の振る舞いを再現したい場合は、このようなイテレータをしたい:

class CCounter(object): 
    def __init__(self, low, high): 
     self.low = low 
     self.high = high 
     self.counter = self.low 
    def __iter__(self): 
     return self 
    def __next__(self): 
     if self.counter > self.high: 
      raise StopIteration() 
     val = self.counter 
     self.counter += 1 
     return val 
関連する問題