Fluent Python読書ノート(一)

4178 ワード

Pythonインタプリタが特殊な構文に遭遇すると、特殊なメソッドを使用して基本的なオブジェクト操作をアクティブにします.これらの特殊なメソッドの名前は2つの下線で始まり、2つの下線で終わります(_getitem_).obj[key]の背後には_getitem__メソッド、obj._を呼び出すgetitem__(key). これらの特殊な方法(デュアル・ダウン・メソッド)は、次の言語アーキテクチャを実現し、サポートし、対話することができます.
  • 反復
  • 集合クラス
  • 属性アクセス
  • 演算子リロード
  • 関数およびメソッドの呼び出し
  • オブジェクトの作成と破棄
  • 文字列表示形式およびフォーマット
  • 管理コンテキスト(withブロック)
  • Python風のカードが山積み
    import collections
    
    #collections.namedtuple                    
    Card=collections.namedtuple('Card',['rank','suit'])
    #>>> card=Card('7','diamonds')
    #>>> card
    #Card(rank='7', suit='diamonds')
    
    class FrenchDeck:
        ranks=[str(n) for n in range(2,11)]+list('JQKA')
        suits='spades diamonds clubs hearts'.split()
    
        def __init__(self):
            self._cards=[Card(rank,suit) for suit in self.suits
                                        for rank in self.ranks]
    
        def __len__(self):
            return len(self._cards)
    
        def __getitem__(self,position):
            return self._cards[position]

    FrenchDeckというクラスでは、deck=FrenchDeck()は、len(deck)を使用して長さを見ることができ、deck[0]を使用して値を取得することができ、Python標準ライブラリを便利に利用することができます.例えば、
    >>> from random import choice
    >>> choice(deck)
    Card(rank='3', suit='hearts')

    なぜならgetitem__方法[]操作をself._に渡したcardsリストのため、deckクラスはスライス操作と反復を自動的にサポートします.
    >>> deck[:3]
    >>> for card in deck:
    ...   print(card)
    >>> for card in reversed(deck): #    
    ...   print(card)

    反復は通常暗黙的であり、例えば1つの集合タイプが実装されていない_contians__メソッドを使用すると、in演算子は順番に反復検索を行います.(_contains_(self,item)inとnot inを呼び出してメンバーが存在するかどうかをテストするとき_contains__ 定義されます.)色と点数によって並べ替えます.
    suit_values=dict(spades=3,hearts=2,diamonds=1,clubs=0)
    
    def spades_high(card):
        rank_value=FrenchDeck.ranks.index(card.rank) # rank     
        return rank_value*len(suit_values)+suit_values[card.suit]

    spades_によるとhigh関数、昇順ソート:
    for card in sorted(deck,key=spades_high):
        print card