zoukankan      html  css  js  c++  java
  • Python

    参考:

    1. Fluent_Python - P430
    2. wiki

    这里说的协议是什么?是让Python这种动态类型语言实现多态的方式。

    1. 在面向对象编程中,协议是非正式的接口,是一组方法,但只是一种文档,语言不对施加特定的措施或者强制实现。
    2. 虽然协议是非正式的,在Python中,应该把协议当成正式的接口。
    3. Python中存在多种协议,用于实现鸭子类型(对象的类型无关紧要,只要实现了特定的协议(一组方法)即可)
    4. 需要成为相对应的鸭子类型,那就实现相关的协议,即相关的__method__。例如实现序列协议(len__和__getitem),这个类就表现得像序列。
    5. 协议是正式的,没有强制力,可以根据具体场景实现一个具体协议的一部分。例如,为了支持迭代,只需实现__getitem__,不需要实现__len__。
    6. 在Python文档中,如果看到“文件类对象“(表现得像文件的对象),通常说的就是协议,这个对象就是鸭子类型。这是一种简短的说法,意思是:“行为基本与文件一致,实现了部分文件接口,满足上下文相关需求的东西。”

    鸭子类型(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__方法,它就是鸭子类型,表现得和序列一样。

  • 相关阅读:
    C/C++指针精髓转载
    彻底搞定c指针系列转载
    vc根据域名获取IP地址 gethostbyname()函数
    try catch finally的执行顺序
    vc2008中mfc字符串转换待续
    C++字符串完全指引(二)转载
    vc随机字符串
    C++字符串完全指引转载
    编写c++程序的优良习惯
    ReportViewer一些技巧
  • 原文地址:https://www.cnblogs.com/allen2333/p/8862341.html
Copyright © 2011-2022 走看看