環境
Python 3.7.13
クラスの場合
以下のような、2から10までの偶数を返すジェネレータがあるとします。
class Even():
def __iter__(self):
yield 2
yield 4
yield 6
yield 8
yield 10
even_gen = Even()
for i in even_gen:
print(i)
出力
2
4
6
8
10
このEven
クラスを継承して、2から10までの偶数に加えて1から9までの奇数も返すEvenOdd
クラスを実装したいとします。
super().__iter__()
でスーパークラス側のgenerator-iteratorオブジェクトを得て一度回し、そのあと(あるいはその前に)サブクラス側の実装をします。以下のようになります。
class EvenOdd(Even):
def __iter__(self):
yield from super().__iter__()
yield 1
yield 3
yield 5
yield 7
yield 9
evenodd_gen = EvenOdd()
for i in evenodd_gen:
print(i)
出力
2
4
6
8
10
1
3
5
7
9
yield from
を使わずに書くと下記のようになります。
class EvenOdd(Even):
def __iter__(self):
super_gen = super().__iter__()
for i in super_gen:
yield i
yield 1
yield 3
yield 5
yield 7
yield 9
関数の場合
先ほどは2から10までの偶数を返すEven
クラスを定義しましたが、同様にeven()
関数を考えてみます。ジェネレータは関数で定義するほうが一般的かもしれません。
def even():
yield 2
yield 4
yield 6
yield 8
yield 10
even_gen = even()
for i in even_gen:
print(i)
このeven()
関数を利用して、あらたに1から9までの奇数も返すようにしたeven_odd()
関数は下記のように実装できます。
def even_odd():
yield from even()
yield 1
yield 3
yield 5
yield 7
yield 9
evenodd_gen = even_odd()
for i in evenodd_gen:
print(i)