2021年8月2日月曜日

for でループさせるためクラスは __next__ を実装する

for でループさせるためクラスは __next__ を実装する

概要

Python は配列などを for ループで回すことができます そのような特性をイテレータと呼びます 自作のクラスでも配列ようにイテレータの機能を実装してあげれば for ループのシーケンスに使えます 今回はサンプルコードを紹介します

環境

  • macOS 11.5
  • Python 3.8.3

サンプルコード: 指定の数字を 0 までループする

class ReverseIterator(object):

    def __init__(self, num):
        self.end = 0
        self.current = num

    def __iter__(self):
        return self

    def __next__(self):
        if self.current == self.end:
            raise StopIteration()
        ret = self.current
        self.current -= 1
        return ret

si = ReverseIterator(10)
for i in si:
    print(i)

サンプルコード: 指定の文字列を 1 文字ずつ表示する

class StringIterator(object):

    def __init__(self, s):
        self.s = s
        self.end = len(s)
        self.current = 0

    def __iter__(self):
        return self

    def __next__(self):
        if self.current == self.end:
            raise StopIteration()
        ret = self.current
        self.current += 1
        return self.s[ret]

si = StringIterator('hoge')
for i in si:
    print(i)

少し解説

実装が必須なのは __iter____next__ になります 特に __next__ が需要で次に渡す情報や終了時の判定はここで行います

今回のサンプルではコンストラクタで開始時と終了時のインデックスを作成しその値になるまで続ける感じにしています

もうこれ以上ループさせたくない場合は StopIteration を raise することで停止してくれます

最後に

list や dict を使ってるとあまり自分でイテレータクラスを作成することはないですがリファクタなどするときにこれはイテレータを持っているなという場合にはこういった手法を使ってリファクタできるかなと思います

参考サイト

0 件のコメント:

コメントを投稿