お聞きしたいこと
Python3.9を利用しています。
forループ中の__getitem__の挙動で質問です。
「初めてのPython(オライリー)」において、forループについて以下の解説がありました。
反復処理が行われる場合には、ビルトイン関数iterが呼び出されて、__iter__メソッドが探されます。__iter__メソッドが存在すれば、イテレータオブジェクトが戻されます。__iter__メソッドが存在しない場合には、__getitem__メソッドが使用されます。IndexError例外が発生するまで、インデクシングが繰り返し行われるのです。
そこで、試しに__getitem__メソッドを搭載したクラスを作成してみました。
Python
1class My_getitem: 2 def __getitem__(self, i): 3 print("__getitem__が呼ばれました") 4 if 2 < i: 5 raise IndexError 6 return i 7 8x = My_getitem() 9for i in x: 10 print(f'forの中です{i=}')
結果は以下のとおりです。
__getitem__が呼ばれました forの中ですi=0 __getitem__が呼ばれました forの中ですi=1 __getitem__が呼ばれました forの中ですi=2 __getitem__が呼ばれました
ここまでは解説通りであることが理解できました。
そこで、forループ内で呼び出されているというiter関数の挙動を確認したく、以下のコードを実行しました。
Python
1class My_getitem: 2 def __getitem__(self, i): 3 print("__getitem__が呼ばれました") 4 if 2 < i: 5 raise IndexError 6 return i 7 8x = My_getitem() 9y = iter(x) 10print(dir(x)) 11print(dir(y)) #yから__getitem__が消えている。 12for i in y: #yには__getitem__が存在しないはずだが、なぜか__getitem__を呼び出すことができている 13 print(f'forの中です{i=}')
結果は以下のとおりです。
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__'] ['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__length_hint__', '__lt__', '__ne__', '__new__', '__next__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__'] __getitem__が呼ばれました forの中ですi=0 __getitem__が呼ばれました forの中ですi=1 __getitem__が呼ばれました forの中ですi=2 __getitem__が呼ばれました
ここでお聞きしたいのですが、なぜオブジェクトyには__getitem__メソッドが存在しないのに、forループ内で呼び出すことができるのでしょうか。
forループの内部で何が起こっているのか教えていただけないでしょうか。
よろしくお願いいたします。
回答2件
あなたの回答
tips
プレビュー
2023/06/12 00:23
2023/06/12 13:12