Alex 在他写的“水禽和抽象基类”一文中指出,即便不注册,抽象基类也 能把一个类识别为虚拟子类。下面是他举的例子,我添加了一些代码, 使用 issubclass 做测试:

>>> class Struggle:

... def __len__(self): return 23

...

>>> from collections import abc

>>> isinstance(Struggle(), abc.Sized)

True

>>> issubclass(Struggle, abc.Sized)

True

经 issubclass 函数确认(isinstance 函数也会得出相同的结 论),Struggle 是 abc.Sized 的子类,这是因为 abc.Sized 实现了 一个特殊的类方法,名为 __subclasshook__。__subclasshook__会改变isinstance和issubclass的行为

class Sized(metaclass=ABCMeta):

__slots__ = ()

@abstractmethod

def __len__(self):

return 0

@classmethod

def __subclasshook__(cls, C):

if cls is Sized:

# 对 C.__mro__ (即 C 及其超类)中所列的类来说,如果类的__dict__ 属性中有名为 __len__ 的属性……

if any("__len__" in B.__dict__ for B in C.__mro__):

# 返回 True,表明 C 是 Sized 的虚拟子类。

return True

return NotImplemented

__subclasshook__ 在白鹅类型中添加了一些鸭子类型的踪迹。我们可 以使用抽象基类定义正式接口,可以始终使用 isinstance 检查,也可 以完全使用不相关的类,只要实现特定的方法即可(或者做些事情让 __subclasshook__ 信服)。当然,只有提供 __subclasshook__ 方 法的抽象基类才能这么做。

在自己定义的抽象基类中要不要实现 __subclasshook__ 方法呢?可 能不需要。我在 Python 源码中只见到 Sized 这一个抽象基类实现了 __subclasshook__ 方法,而 Sized 只声明了一个特殊方法,因此只 用检查这么一个特殊方法。鉴于 __len__ 方法的“特殊性”,我们基本 可以确定它能做到该做的事。但是对其他特殊方法和基本的抽象基类来 说,很难这么肯定。例如,虽然映射实现了 __len__、__getitem__ 和 __iter__,但是不应该把它们视作 Sequence 的子类型,因为不能 使用整数偏移值获取元素,也不能保证元素的顺序。当 然,OrderedDict 除外,它保留了插入元素的顺序,但是不支持通过 偏移获取元素。

在你我自己编写的抽象基类中实现 __subclasshook__ 方法,可靠性 很低。我可不相信随便一个实现或继承了 load、pick、inspect 和 loaded 的类(如 Spam)的行为一定像 Tombola。程序员最好让 Spam 继承 Tombola,至少也要注册(Tombola.register(Spam)),从而确 保这一点。当然,自己实现的 __subclasshook__ 方法还可以检查方 法签名和其他特性,但我觉得不值得这么做。

python白鹅类型_fluent python 11.10节 鹅的行为有可能像鸭子相关推荐

  1. python每日一练(2021/11/10)字符串类型的cookie转化为字典类型

    将一段字符串类型的cookie转化为字典类型 思路:将cookie用:分割,然后遍历它用'='再次分割存入数组.最后将下标为0的作为键,下标为1的作为值 知识点: 1.字典推导式格式:{键:值 for ...

  2. python画散点图类型-绘制python中的线和散点图

    我目前正在从Coursera( https://www.coursera.org/learn/ml-foundations/lecture/6wD6H/visualizing-predictions- ...

  3. 【Python入门教程】教你如何10分钟入门Python!(超详细)

    前言:我们在职业生涯中都需要通过各种方式来提升自身的专业能力,在这里我们建了一个Q群[856833272]欢迎大家来交流学习,更多资料免费分享还有免费直播课领取!学习路上有伙伴,学习路上不孤单!(也可 ...

  4. python移动图形工作站_让Python跑得更快

    原标题:让Python跑得更快 点击关注 异步图书,置顶公众号 每天与你分享 IT好书 技术干货 职场知识 Tips 参与文末话题讨论,即有机会获得异步图书一本. Python很容易学.你之所以阅读本 ...

  5. Python服务器开发一:python基础

    Python服务器开发一:python基础 Python(蟒蛇)是一种动态解释型的编程语言.Python可以在Windows.UNIX.MAC等多种操作系统上使用,也可以在Java..NET开发平台上 ...

  6. 自学python编程免费教程-Python十分钟入门 自学python基础教程送你参考

    python十分钟入门.简介Python是一种动态解释型的编程语言.Python可以在Windows.UNIX.MAC等多种操作系统上使用,也可以在Java..NET开发平台上使用. 特点 1 Pyt ...

  7. python编程100例海绵宝宝-python基础1(理论基础)

    1.python是什么语言 2.python的发展史 3.python2与python3的区别 4.python的语言类型 5.python的优缺点 6.IDLE是什么 7.变量是什么 一.pytho ...

  8. python白鹅类型_关于python鸭子类型和白鹅类型

    1,白鹅类型 白鹅类型对接口有明确定义,比如不可变序列(Sequence),需要实现__contains__,__iter__,__len__,__getitem__,__reversed__,ind ...

  9. 13.Python中的白鹅类型 (Goose Typing)

    <Python编程的术与道:Python语言进阶>视频课程 <Python编程的术与道:Python语言进阶>视频课程链接:https://edu.csdn.net/cours ...

最新文章

  1. 71页《乌镇智库:全球人工智能发展报告(2018)》PDF下载
  2. 模拟浏览器发送请求报文
  3. 几个UI Prototype应用的使用感受
  4. lex/flex 笔记
  5. Linux 进阶笔记(二)
  6. dlna和miracast可以共存吗_AirPlay、DLNA、Miracast三大无线技术介绍
  7. springmvc拦截器对请求参数解密_SpringMVC拦截器如何修改请求参数
  8. leetcode343. 整数拆分(dp)
  9. The current branch is not configured for pull N...
  10. java 反射 getClass()
  11. java中的加加++的疑惑?
  12. 联想家庭版 mysql_联想自带win7家庭版..
  13. 回声状态网络(ESN)教程
  14. python-数据分析-pandas
  15. 华为:实现流程优化的方法
  16. Mirrored String I Gym - 101350H (水)判断回文
  17. 简单理解float和double、单精度和双精度
  18. spss基本总结——因子分析
  19. 可禁用计算机服务,Windows 10系统下哪些服务可以关闭?
  20. Linux Weblogic 10.3.6安装和漏洞补丁过程

热门文章

  1. 大数据分析工具BI应用在哪方面
  2. 大数据技术落地需要注意哪些问题
  3. excel显著性检验_数据分析系列 10/32 | Excel方差分析之单因素方差分析
  4. Python3.x+pycharm+Anaconda中缩小打包的.exe体积的方法
  5. android vrs技术,VRS技术分析研究及应用
  6. idea 调试java技巧_Intellij IDEA Debug 调试技巧
  7. mod libs 课堂
  8. 通过Docker进程pid获取容器id
  9. 主键,唯一索引,唯一约束三者之间的联系与区别
  10. input 下面的span 标签 作为下拉框选项的点击