ゼロベース入門学習Python(25):魔法方法(5)カスタムシーケンスと反復器


ゼロベース入門学習Python(25):魔法方法(5)カスタムシーケンスと反復器
コンテナタイプのプロトコル:可変コンテナをカスタマイズする場合は、__len__(self) __getitem__(self,key)メソッドを定義する必要があります.カスタマイズするコンテナが可変である場合、上記の2つの方法を定義するだけでなく、__setitem__(self,key,value) __delitem__(self,key)の方法を定義する必要があります.ここで、__len__(self)は、len()によって呼び出されたときの動作を定義する.__getitem__(self,key)は、self[key]に相当する容器内の指定された要素を取得する動作を定義する.__setitem__(self,key,value)は、self[key] = valueに相当する設定容器内の指定された要素の動作を定義する.__delitem__(self,key)は、del self[key]に相当するコンテナ内の指定された要素を削除する動作を定義します.
次に、可変コンテナのカスタマイズについて、可変カスタムリストを作成することによって、リスト内の各要素がアクセスされた回数を記録します.
>>> class CountList:
        def __init__(self, *args):            #        
            self.values = [x for x in args]   #          value
            self.count = {}.fromkeys(range(len(self.values)),0)    #    ,                   0
        def __len__(self):
            return len(self.values)
        def __getitem__(self, key):
            self.count[key] += 1              #   k         
            return self.values[key]           #        

>>> c1 = CountList(1,3,5,7,9)                 #        
>>> c2 = CountList(2,4,6,8,10)
>>> c1[1]                                     #     c1   1    
3
>>> c2[1]                                     #     c2   1    
4
>>> c1[1] + c2[1]                             #     c1[1] c2[1]
7
>>> c1.count                                  #     count  ,   1        2
{0: 0, 1: 2, 2: 0, 3: 0, 4: 0}
>>> c2.count
{0: 0, 1: 2, 2: 0, 3: 0, 4: 0}
>>> c1[1]
3
>>> c1.count                                  #     c1[1]  ,         1
{0: 0, 1: 3, 2: 0, 3: 0, 4: 0}

可変容器のカスタマイズはみんなに自分で練習してもらいます.魔法の方法の最後に、反復器を紹介します.iter():コンテナオブジェクト(シーケンス(リスト、メタグループ、文字列)、辞書、ファイル)に対してiter()を呼び出すと反復器が得られ、next()を呼び出すと反復器は次の値を返し、反復器に値が戻らないとPythonはStopIterationの異常を放出します.
>>> string = "Jessica"
>>> it = iter(string)                 #it      
>>> next(it)                          #  next   ,     it     
'J'
>>> next(it)
'e'
>>> next(it)
's'
>>> next(it)
's'
>>> next(it)
'i'
>>> next(it)
'c'
>>> next(it)
'a'
>>> next(it)                          #        next     StopIteration  
Traceback (most recent call last):
  File "<pyshell#11>", line 1, in <module>
    next(it)
StopIteration
>>> it = iter(string)                  #         
>>> while True:                        #             
        try:
            each = next(it)
        except StopIteration:
            print("There is no more data.")
            break;
        print(each)

J
e
s
s
i
c
a
There is no more data.

反復器の魔法方法:__iter__(self):反復器自体、すなわちreturn selfを返す;__next__():反復器の反復規則が決定される.
>>> class Fibs:                          #     ,       
        def __init__(self, n = 10):      #       ,      n      
            self.a = 0
            self.b = 1
            self.n = n
        def __iter__(self):              #   
            return self
        def __next__(self):
            self.a, self.b = self.b, self.a + self.b     #     ,         ,        
            if self.a > self.n:          #      n      ,     ,         
                raise StopIteration
            return self.a

>>> fibs = Fibs()                        #     10      
>>> for each in fibs:
        print(each)

1
1
2
3
5
8
>>> fibs = Fibs(100)                     #     100      
>>> for each in fibs:
        print(each)

1
1
2
3
5
8
13
21
34
55
89

ゼロベース入門学習Python(24):魔法の方法(4)記述子