【pythonマジックメソッド】反復器(_iter__および__next_)


pythonにはたくさんあります.開始と終了の関数は,それらを用いて多くの複雑な論理コードを完成させ,コードの簡潔性を向上させ,本論文では主に反復器で用いられるマジック法をまとめ,主にコード例で説明した.__iter____next__実はここでは反復器という概念を導入する必要があります.よく見られるのは、for文を使用するとき、python内部ではforの後ろのオブジェクトに内蔵関数iterを使用しています.例えば、
a = [1, 2, 3]
for i in a:
    do_something()

pythonの内部では、次のような変換が行われています.
a = [1, 2, 3]
for i in iter(a):
    do_something()

ではiterは何を返しているのでしょうか.反復オブジェクトで、主にクラスにマッピングされています.iter__を選択します.next__の双曲線コサインを返します.この言葉を理解することに注意してください.例えば、
class B(object):
    def __next__(self):
        raise StopIteration

class A(object):
    def __iter__(self):
        return B()

Aというクラスが1つの__を実現したことがわかります.iter__関数は、B()のインスタンスオブジェクトを返します.ここで、Bには__が実装されています.next__この関数です.
以下にいくつかの概念を導入します:Iterable:反復能力のあるオブジェクト、1つのクラス、実現しました_iter__,では、反復能力があると考えられます.通常、この関数は実装を返さなければなりません.next__のオブジェクトは、自分が実現したらselfに戻ることができます.もちろん、この戻り値は必須ではありません.Iterator:反復器(もちろんIterable)、同時に_iter__および_next__上の例では、A()はIterableであってもよいが、A()とB()はIteratorとは言えない.Aは__しか実現していないからだ.iter__,Bは__しか実現していませんnext__().
collectionsのタイプを使用して検証できます.
class B(object):
    def __next__(self):
        raise StopIteration

class A(object):
    def __iter__(self):
        return B()


from collections.abc import *

a = A()
b = B()
print(isinstance(a, Iterable))
print(isinstance(a, Iterator))

print(isinstance(b, Iterable))
print(isinstance(b, Iterator))

結果は次のとおりです.
True
False
False
False

Bというクラスを少し修正しましょう.
class B(object):
    def __next__(self):
        raise StopIteration

    def __iter__(self):
        return None

class A(object):
    def __iter__(self):
        return B()


from collections.abc import *

a = A()
b = B()
print(isinstance(a, Iterable))
print(isinstance(a, Iterator))

print(isinstance(b, Iterable))
print(isinstance(b, Iterator))

結果は次のとおりです.
True
False
True
True

本当の反復器の上でいくつかのプレゼンテーションをしただけで、ここではiter関数を呼び出すと、反復オブジェクトが生成され、要求されます.iter__インプリメンテーションを返さなければなりませんnext__のオブジェクトは、next関数でこのオブジェクトの次の要素にアクセスでき、反復を継続したくない場合にStopIterationの例外を投げ出すことができます(for文はこの例外をキャプチャし、自動的にforを終了します)、次にrange関数のような独自の機能を実現します.
class MyRange(object):
    def __init__(self, end):
        self.start = 0
        self.end = end

    def __iter__(self):
        return self

    def __next__(self):
        if self.start < self.end:
            ret = self.start
            self.start += 1
            return ret
        else:
            raise StopIteration

from collections.abc import *

a = MyRange(5)
print(isinstance(a, Iterable))
print(isinstance(a, Iterator))

for i in a:
    print(i)

結果は次のとおりです.
True
True
0
1
2
3
4

次にnext関数を使用してシミュレーションします.
class MyRange(object):
    def __init__(self, end):
        self.start = 0
        self.end = end

    def __iter__(self):
        return self

    def __next__(self):
        if self.start < self.end:
            ret = self.start
            self.start += 1
            return ret
        else:
            raise StopIteration

a = MyRange(5)
print(next(a))
print(next(a))
print(next(a))
print(next(a))
print(next(a))
print(next(a)) #           ,           

明らかな利点は、生成されるたびに1つのデータが生成されることです.どういう意味ですか.例えば、私は[0,1,2,3...]を10億まで遍歴します.リストを使用すると、すべてメモリにロードされますが、反復器を使用すると、使用(つまりnextが呼び出された)ときに対応する数字が生成されることがわかります.これによりメモリを節約できます.これは怠惰なロード方法です.
まとめはcollectionを用いることができる.absの中のIteratorとIterableはisinstance関数と協力して1つのオブジェクトが反復可能かどうかを判断し、反復器オブジェクトiterが実際に__にマッピングされているかどうかを判断します.iter__関数は実装されている限りiter__のオブジェクトは反復可能なオブジェクト(Iterable)であり、通常は実装された_を返すべきである.next__の相手(この要求は強制しないが)、自分が実現したら_next__,もちろん自分に戻って同時に実現することもできますiter__および_next__反復器(Iterator)です.もちろん反復可能なオブジェクトです.next__反復が完了すると、StopIteration例外for文が放出され、このStopIteration例外が自動的に処理され、forループが終了します.
作者:Liburroリンク:https://www.jianshu.com/p/1b0686bc166d出典:簡書の著作権は作者の所有である.商業転載は著者に連絡して許可を得てください.非商業転載は出典を明記してください.