Python.use(better)

前の記事記事一覧次の記事
Python.use(better)


組み込み型 list《05》

def __iter__(self)


《関連記事》

-

事例:モジュールを起動する

■ 全項目を確認する

全ステップの「項目」を確認するには、関数 do を利用します。

$ python -i myList.py
>>> do()
...
 5: step05 -- def __iter__(self)
■ 各項目を実行する

各ステップの「動作」を確認するには、関数 do の実引数を指定します。

>>> do(5)
...
>>> # ---------------------------------------- append
>>> s = myList(); s

>>> s.append('A'); s
['A']
>>> s.append('B'); s
['A', 'B']
>>> s.append('C'); s
['A', 'B', 'C']
>>> # ---------------------------------------- __len__
>>> s = myList(); s, len(s)
(, 0)
>>> s.append('A'); s, len(s)
(['A'], 1)
>>> s.append('B'); s, len(s)
(['A', 'B'], 2)
>>> s.append('C'); s, len(s)
(['A', 'B', 'C'], 3)
>>>
  • 前 step04 と同じ結果が得られます。

特殊メソッド __iter__

組み込み関数 iter に呼応して、その動作を規定するのが、特殊メソッド __iter__ です。

>>> class myList(object): pass

>>> x = myList(); x
<__main__.myList object at 0x124ddd0>
>>> iter(x)
...
TypeError: 'myList' object is not iterable

このメソッドを定義せずに、そのインスタンスiter を適用すると、例外 TypeError を生成します。

>>> for e in x: print()
...
TypeError: 'myList' object is not iterable

事例:コードの解説

def step05():
    """def __iter__(self)"""

    class myList(object):
        def __repr__(self):                  #1:
            s = []
            for e in self:
                s.append(repr(e))
            return "[%s]"%", ".join(s)

        def __len__(self):                   #2:
            n = 0
            for _ in self:
                n += 1
            return n

        def __iter__(self):         #3:
            node = self.head.next
            while node:
                yield node.item
                node = node.next

《TIPS》メソッド __iter__ を定義すると、self と記述するだけで、それを実現する方法(how)に依存しない、抽象表現(what)が可能になります。

■ #1: オブジェクトの文字列表現

メソッド __repr__ は、組み込み関数 repr() に呼応して、オブジェクトの文字列表現を規定します。

        def __repr__(self):                 #1: BEFORE
            s = []
            node = self.head.next
            while node:
                s.append(repr(node.item))
                node = node.next
            return "[%s]"%", ".join(s)

メソッド __iter__ を規定する前は、連結リストを実現する方法(how)に依存する、具体的な処理を記述する必要があります。

        def __repr__(self):                  #1: AFTER
            s = []
            for e in self:
                s.append(repr(e))
            return "[%s]"%", ".join(s)
  • 連結リスト self の各ノード e を順にたどりながら、各要素の文字列表現 repr(e) をリスト s に追加 append します。
■ #2: リストの長さ(要素数

メソッド __len__ は、組み込み関数 len() に呼応して、リストの長さ(要素数)を与えます。

        def __len__(self):                   #2: BEFORE
            n = 0
            node = self.head.next
            while node:
                n += 1
                node = node.next
            return n

メソッド __iter__ を規定する前は、連結リストを実現する方法(how)に依存する、具体的な処理を記述する必要があります。

        def __len__(self):                   #2: AFTER
            n = 0
            for _ in self:
                n += 1
            return n

メソッド __iter__ を規定した後は、ただ self と記述するだけで、それを実現する方法(how)に依存しない、抽象表現(what)が可能になります。

  • 連結リスト self の各ノード _ を順にたどりながら、変数 n の値をひとつずつ増やします。

》こちらに移動中です《
TOP

Last updated♪2009/10/07