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. oracle bulk collect
  2. java服务端同时接收和发送_如何实现客户端接收数据和发送数据的同步?
  3. 给WIN2003 IIS SQL服务器安全加固
  4. 和华为hr电话面试的反思
  5. Git 忽略提交 .gitignore
  6. 牛客网 【每日一题】4月10日 二分图染色(弱化版)
  7. IDEA必备插件提高企业开发效率(强烈推荐)
  8. python点击网页按钮 没有id_button没有id,没有onclick事件。点击却有提交的功能,如何实现的?...
  9. 齐博cms任意登陆漏洞
  10. unity怪物攻击玩家减血_Unity RPG游戏攻击的判定
  11. 2013蓝桥杯C++B:第39阶台阶(递归法);前缀判断
  12. nginx location的命中过程
  13. 积分简明笔记-第一类曲线积分的类型
  14. Windows上安装PyV8
  15. Hadoop基础组件思维导图
  16. Druid连接池核心原理
  17. 当当网上书店头部和尾部——JS源码
  18. Python的优势和劣势
  19. 1214_嵌入式硬件常识积累_什么是TTL电平
  20. Google SketchUp SKP文件转OBJ 专业版注册机

热门文章

  1. Combine的使用案例
  2. python openpyxl合并单元格_用openpyxl分析xlsx文件的合并单元格
  3. ios 去掉底部状态栏,隐藏ios 9中的状态栏
  4. pythonos模块怎么设置_Python OS模块如何使用?
  5. SparkStreaming安全消费Kafka数据
  6. Linux高性能网络:协程系列01-前言
  7. Kubernetes 架构与设计
  8. Picasso源码阅读笔记三
  9. PHP写webservice服务端
  10. linux shutdown 命令