Python中的协议和鸭子类型

参考:

  1. Fluent_Python - P430
  2. wiki

这里说的协议是什么?

  1. 在面向对象编程中,协议是非正式的接口,只在文档中定义,在代码中不定义。
  2. 在Python中,应该把协议当成正式的接口。
  3. Python中存在多种协议,用于实现鸭子类型。(需要成为相对应的鸭子类型,那就实现相关的协议,即相关的__method__)

鸭子类型(Duck Typing)

  1. When I see a bird that walks like a duck and swims like a duck and quacks like a duck, I call that bird a duck. - James Whitcomb Riley
  2. 不关注对象的类型,而关注对象的行为(方法)。它的行为是鸭子的行为,那么可以认为它是鸭子。

例子1. 让FrenchDeck类表现的像Python的序列一样,FrenchDeck就是鸭子类型。

  1. FrenchDeck类是哪个类的子类,是什么类型,都没有关系。只要提供所需的方法即可,例如表现得像序列一样。
  2. Python的序列协议只需要__len__和__getitem__两个方法。
import collections

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

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._cars)

    def __getitem__(self, position):
        return self._cards[position]

这里,FrenchDeck实现了Python序列协议所需的__len__和__getitem__方法,它就是鸭子类型,表现得和序列一样。

猜你喜欢

转载自www.cnblogs.com/allen2333/p/8862341.html