イテレータ??ジェネレータ??
Qiitaの記事を漁っていると、
「ジェネレータはイテレータの一種」
「ジェネレータはイテレータを返す関数」
など、相反する記述が見受けられます。
信用できるのはやはり公式ドキュメントだと思い、読み込んできました。
この記事で(pythonにおける)イテレータの意味、ジェネレータの意味をはっきりさせます。
ジェネレータ(generator)とは
そもそもジェネレータには2つの意味がある(!)
ジェネレータは文脈によって意味が異なり、
- ジェネレータ関数(generator function)
- ジェネレータイテレータ(generator iterator)
の2つの意味がある(参考)
それぞれの意味は、
- ジェネレータ関数
- ジェネレータイテレータというオブジェクトを返す関数
- yield式を持つ
- ジェネレータイテレータ
- ジェネレータ関数で生成されるオブジェクト
このジェネレータイテレータがイテレータの一種。
ではイテレータとはなんなのか。
イテレータとは
データの流れを表現するオブジェクトである。
以下の2つのメソッドをサポートする。
- iterator.__iter__()...iter(itarator)と等価
- イテレータオブジェクト自身を返す
- iterator.__next__()...next(iterator)と等価
- 次のアイテムを返す
イテレータ(iterator)とジェネレータイテレータ(generator iterator)の違い
まず前提として、__iter__()か__getitem__()メソッドをサポートするobjからiter(obj)によってイテレータを得ることができる。
察しのよいかたはもう気付いたかもしれないが、以上の話をまとめると、
class Object():
def __iter__(self):
...
object = Object()
このときのiter(object)はイテレータであり、
class Object():
def __iter__(self):
...
yield hoge
object = Object()
このときのiter(object)はイテレータであり、かつジェネレータイテレータでもあります。
要は、もととなるコンテナオブジェクトの__iter__()メソッドにyieldがあるかないかの差なのでした。
備考
やはり公式ドキュメントに勝るものはないです。
もしもこの記事に間違った記述を見つけられた方はコメント欄などでご一報下さると幸いです。