Wlgls 冲鸭!

第一章 Python的魔法方法


在python中,我们碰到特殊的语法时,会使用特殊方法去激活一些基本的对象操作,这些特殊方法的名字以两个下划线__开头,两个下划线__结尾

比如 obj[key]的背后就是__getitem__方法,及为了求得obj[key], 解释器会调用obj.__getitem__(key)

>>> obj = {'a': 1, 'b':2}
>>> obj
{'a': 1, 'b': 2}
>>> obj['a']
1
>>> obj.__getitem__('a')
1

这也就意味着我们可以通过修改这些方法,来得到我们想要得到的结果

import collections

Card = collections.namedtuple('Card', ['rank', 'suit'])

class FrenchDeck:
    ranks = [str(n) for n in list(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]

假如我们没有定义__len__方法,但是我们依旧调用它的话

beer_deck = FrenchDeck()
print(len(deck))

这将得到一个错误

<class '__main__.Card'>
Traceback (most recent call last):
  File "model_data.py", line 21, in <module>
    print(len(deck))
TypeError: object of type 'FrenchDeck' has no len()

但是如果我们定义他的时候,我们通过修改返回值就可以得到不同的结果

import collections

Card = collections.namedtuple('Card', ['rank', 'suit'])

class FrenchDeck:
    ranks = [str(n) for n in list(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]
    ''' 如果使用这个,len(deck) == 52
    def __len__(self):
        return len(self._cards)
    '''

    '''而这一个将会得到53
    def __len__(self):
        return len(self._cards)+1
    '''
deck = FrenchDeck()
print(len(deck))