Pythonの内部メカニズム-forループ

Pythonでは、forループを使用して、コンテナオブジェクトの要素を反復できます。コンテナオブジェクトには、リスト(list)、タプル(tuple)、ディクショナリ(dict)、セット(set)などが含まれます。しかし、なぜこれらのオブジェクトをforループを使用して操作できるのでしょうか。

まず、試す簡単なクラスを定義します。

classTestRange:
 def __init__(self, num):
 self.num = num
for i inTestRange(10):print(i)

# 出力
Traceback(most recent call last):
 File "<stdin ", line 1,in<module 
TypeError:'TestRange' object is not iterable

エラーメッセージは、「TestRange」オブジェクトが反復可能なオブジェクトではないことを示しています。では、反復可能なオブジェクトとは何ですか?

反復可能なオブジェクトでは、 __iter__の魔法のメソッドを実装する必要があり、このメソッドの戻り値は反復子である必要があります。では、イテレーターとは何ですか?

イテレーターは、 __next__マジックメソッドを実装するだけで済みます。

例としてリストを見てください:

 nums =[13,12,33]
 iter_ret = nums.__iter__() #xにはこのメソッドがあり、リストが反復可能であることを示し、メソッドは反復子を返します
 iter_ret
< list_iterator object at 0x100f32198 

 iter_ret.__next__()13
 iter_ret.__next__()12
 iter_ret.__next__()33
 iter_ret.__next__()Traceback(most recent call last):
 File "<stdin ", line 1,in<module 
StopIteration

分析:

上に示したように、 __iter__メソッドはリストnumsに実装され、イテレーターが返され、 __next__メソッドがイテレーターに実装されます。 __next__を呼び出すプロセスでは、 StopIterationのエラーが発生するまで要素をnumsで返します。

実際、forステートメントの機能は似ています。 ** forステートメントの内部メカニズムは**:

以前のTestRangeは、イテレータープロトコルに2つのメソッドを実装していなかったため、エラーを報告しました。今後も改善を続けてください。

classTestRange:
 def __init__(self, _max):
 self.i =0
 self._max = _max

 def __iter__(self):return self

 def __next__(self):if self.i < self._max:
  i = self.i
  self.i +=1return i
 else:
  # 停止条件に達すると、この例外がスローされます
  raise StopIteration()

# テストを実行します
for i inTestRange(3):print(i)
# 出力
 012

分析:

このクラスはすでに __next__メソッドを実装しているため、このクラスに基づいて作成されたオブジェクト自体がイテレーターです。また、反復可能オブジェクトには __iter__メソッドが必要であり、反復子を返す必要があるため、 __iter__はオブジェクト自体を selfします。

総括する

これまで、Python-forループの内部メカニズムに関するこの記事を紹介しました。関連するpython forループのコンテンツについては、ZaLou.Cnの以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後、ZaLou.Cnをさらにサポートしていただければ幸いです。 !

Recommended Posts

Pythonの内部メカニズム-forループ
Python(7)の基盤を統合する
Python(6)の基盤を統合する
「Pythonの基盤を統合する」(1)
Pythonの基盤を統合する(3)