Pythonのiterableオブジェクトの理解方法

4797 ワード

転載は出典を明記してください.https://www.jianshu.com/u/5e6f798c903a[^*]は脚注を表し、文末では対応する接続を表示できますが、この構文はサポートされていません.
まず,コンテナとiterableの間には必然的な関連性はない.オブジェクトは、iterable以外のコンテナであってもよいし、非コンテナのiterable(ファイルオブジェクトやソケットオブジェクトなど)であってもよい.さらに、コンテナは通常有限であり、iterableは無限のデータソースを表すことができる.コンテナについては、Pythonのコンテナオブジェクトの理解方法について別の記事を参照してください.
iterableは、公式ドキュメントの文脈に次の2つの意味があります.
  • 1つ目は特に実現した__iter__メソッドのオブジェクトを指す[^2].本節以降ではそのようなオブジェクトをIterableObjcと呼ぶ.Tips:IteratorおよびGeneratorともにIterableObjcに属する.
    from collections import abc
    
    
    class IterableObjc:
        def __iter__(self):
            cont = 0
            while cont < 3:
                cont += 1
                yield cont
    
    
    a_iterable = IterableObjc()
    assert isinstance(a_iterable, abc.Iterable)  #    
    
  • 2つ目はiterableを抽象概念とする.内蔵関数iter()[^5]が許容できる対象であれば、iterableとみなされる(ここでは特にiter()の単一パラメータ形式を指し、第2パラメータは含まない).したがって、__iter__()または__getitem__()のいずれかを定義すれば、iterableとして認定される.ただし、__getitem__()のオブジェクトのみが定義されており、IterableObjcではない.2番目の意味に含まれるオブジェクトの範囲は、1番目の意味よりも大きく、IterableObjcはiterableのサブセットであると考えられる.このセクションの後続のセクションで説明するiterableは、2つ目の意味を使用します.
    class GetitemObjc:
        def __getitem__(self, item):
            cont = 0
            while cont <= item:
                cont += 1
                if cont >= 5:
                    raise StopIteration()
            return cont
    
    
    a_getitem = GetitemObjc()
    assert isinstance(a_getitem, abc.Iterable)  #   
    

  • 1.iterableとforループ
    iterableをforループに使用する場合は、自分で呼び出す必要はありませんiter()反復オブジェクトを自分で処理する必要もありません.for文は、ループ中に反復器を保存するための一時的な無名変数を自動的に作成します.逆アセンブル(disassemble)により、より直感的に理解できるforループの実行手順、コードは以下の通りである.
    dis.dis("for _ in iterable: pass")
    

    出力:
    1           0 SETUP_LOOP              12 (to 14)
                  2 LOAD_NAME                0 (iterable)
                  4 GET_ITER
            >>    6 FOR_ITER                 4 (to 12)
                  8 STORE_NAME               1 (_)
                 10 JUMP_ABSOLUTE            6
            >>   12 POP_BLOCK
            >>   14 LOAD_CONST               0 (None)
                 16 RETURN_VALUE
    

    出力を観察することにより、可視解釈器が明示的にGET_ITERを呼び出し、これは呼び出したiter(iterable)に相当する.つまりfor文は自動的に呼び出されるiter(iterable)となり、iterableオブジェクトを1つの反復器に変換することになる[^6].FOR_ITER命令(next()メソッドに相当)で次の要素を取得できるようにする.注:解釈器が最適化されているため、バイトコード命令からすべてのプロセスを直接観察することはできません.
    2.iterableと内蔵関数
    iterableは、組み込み関数など、順序オブジェクトが必要な場所でも使用できます.
  • any(iterable)
  • class list([iterable])
  • map(function, iterable, ...)
  • ....

  • 内蔵関数としては、iterableパラメータに第2の意味が用いられており、厳密な意味ではないIterableObjc.
    たとえば、文書に組み込まれている関数any(iterable)については、以下のように解釈します.
    反復可能(iterable)オブジェクトの要素のブール値がTrueの場合、Trueが返されます.反復可能オブジェクトが空の場合は、Falseを返します.次のコードに相当します.
    def any(iterable):
        for element in iterable:
            if element:
                return True
        return False
    

    これにより,内蔵関数にiterableパラメータがある場合,iterableを反復器に変換してから処理することが推測される.内蔵関数の内部ではfor間接変換をループしてもよいし、直接使用してもよいiter()変換を行う(ただし、内蔵関数はCで実現されているが、ここでは1つの考え方を与えるためにのみ)
    3.IterableObjcと_iter__
    まず2つの概念を明確にします.
  • IterableObjc:すべて実現__iter__の対象はIterableObjcと呼ぶことができる
  • 反復器:同時実現__iter__および__next__の対象であり、反復器もIterableObjcに属する.

  • 本質的には__iter__メソッドは反復器を返すために存在し、容器に反復器を提供する必要がある場合に呼び出される.しかし、IterableObjc自体も反復器である可能性があるため、次の2つのケースが発生します.
    #      :IterableObjc       
    class IterableObjc:
        """
              ,    __iter__   ,
                 id      ,        。
        """
        def __iter__(self):
            """        ,         """
            cont = 0
            while cont < 3:
                cont += 1
                yield cont
                
    #      :IterableObjc       
    class IteratorObjc:
        """
              ,    __iter__   ,
                 ,       id      。
        """
        def __iter__(self):
            self._count = 0
            #          
            return self
    
        def __next__(self):
            while self._count < 3:
                self._count += 1
                return self._count
    

    脚注:[1]:言語参照-3.1.Objects,values and types[2]:標準ライブラリ8.4.collections.abc—Abstract Base Classes for Containers[3]:Iterables vs.Iterators vs.Generators|Python反復オブジェクト、反復器、ジェネレータを完全に理解する[4]:Glossary用語表[5]:iter(object[,sentinel])[6:言語参照-8.3.Theforstatement[7]:標準ライブラリ-Iterator Type[8]:言語参照-3.3.3.7.Emulating container types