python抽象基类之_subclasshook_方法

Python的鸭子特性(duck typing)

Python中自定义的类只要实现了某种特殊的协议,就能赋予那种行为,举一个简单的例子:

class A:def __len__(self):return 0
a = A()
print(len(a))

如上所示,自己定义了一个类,实现了__len__的魔法方法,就可以使用内置函数len()获取对象长度。如果实现了__getitem__魔法方法,自定义对象就能称为”序列类型”,可以使用类似list序列那样的操作,比如a[1]获取第2个元素......

Python的白鹅特性(抽象基类)

在Java中,有interface接口的概念,而在Python中没有这个概念,取而代之的是抽象基类。在Python中定义一个抽象基类如下:

import abc
class Base(abc.ABC):@abc.abstractmethoddef func(self):"""doc"""

只需要实现func的接口即可

class MyClass(Base):def func(self):pass

Python虚拟子类(使用__subclasshook__)

Python原生定义了抽象基类Sized,里面实现了__len__方法,我们可以自定义类来继承Sized,实现里面的__len__方法,Sized源码如下:

class Sized(metaclass=ABCMeta):__slots__ = ()@abstractmethoddef __len__(self):return 0@classmethoddef __subclasshook__(cls, C):if cls is Sized:return _check_methods(C, "__len__")return NotImplemented

如上所示,我们看到了它实现了__subclasshook__方法,检查子类和子类的mro上所有的类是否有__len__方法,如果没有,返回NotImplemented。当然我们不必继承Sized,而是使用虚拟子类(virtual subclass)技术,只实现__len__协议,隐式继承了Sized。

下面我们仿造Sized自定义一个抽象基类

import abc
class Base(abc.ABC):@abc.abstractmethoddef my_protocol(self):"""自定义协议"""@classmethoddef __subclasshook__(cls, subclass):if cls is Base:if any("my_protocol" in B.__dict__ for B in subclass.__mro__):return Truereturn NotImplemented

接下来我们定义一个子类,隐式继承Base

#并没有显式继承Base
class MyClass:def my_protocol(self):pass
if __name__ == '__main__':k = MyClass()print(isinstance(k, Base))  #Trueprint(issubclass(MyClass, Base))#Trueprint(Base._abc_impl)

如上所示,我们只需要实现my_protocol协议,就会隐式继承自抽象基类,这样就实现了虚拟子类的创建。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/305666.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大数据Doris(四十三):创建物化视图

文章目录 创建物化视图 一、首先你需要有一个Base表

【基础篇】五、类的双亲委派机制

文章目录 1、双亲委派机制2、Java代码中去主动加载一个类3、“父”加载器4、Q & A5、打破双亲委派机制 1、双亲委派机制 JVM中有多个类加载器,某个类A,到底该由谁去加载 ⇒ 双亲委派机制 该机制的作用: 保证类加载的安全性:避…

一招搞定找不到vcruntime140_1.dll无法继续执行此代码

在计算机使用过程中,我们经常会遇到一些错误提示,其中最常见的就是“找不到指定的模块”或“无法加载某某.dll文件”。而其中一个常见的问题就是vcruntime140_1.dll丢失。那么,vcruntime140_1.dll到底是什么?为什么会出现丢失的情…

django之drf框架(排序、过滤、分页、异常处理)

排序 排序的快速使用 1.必须是继承GenericAPIView及其子类才能是用排序 导入OrderingFilter类,from rest_framework.filters import OrderingFilter 2.在类中配置类属性 filter_backends[OrderingFilter] 3.类中写属性 ordering_fields [price,id] # 必须是表的…

【快速全面掌握 WAMPServer】04.人生初体验

网管小贾 / sysadm.cc 我们在前面的教程中为小伙伴们详细地介绍了 WampServer 的安装方法,相信大家对于如何安装应该已经有了一个比较完全的掌握。 在完全掌握安装方法之后,我们还可以更加便捷地使用我为大家提供的一键安装批处理程序来快速搞定安装部署…

Vue 问题解决

一、问题:TypeError: (0 , _message.default) is not a function 当没有default时,在其他页面import引入的时,必须加{}。 二、问题:Vue前端页面的表格数据总是一行一行的显示 使用Async/Await来解决前端数据一行一行显示的问题。可以将获取部…

磁盘管理 :逻辑卷、磁盘配额

一 LVM可操作的对象:①完成的磁盘 ②完整的分区 PV 物理卷 VG 卷组 LV 逻辑卷 二 LVM逻辑卷管理的命令 三 建立LVM逻辑卷管理 虚拟设置-->一致下一步就行-->确认 echo "- - -" > /sys/class/scsi_host/host0/scan;echo "- -…

如何将弹性公网IP绑定到负载均衡CLB

创建的CLB实例为私网类型,没有公网IP,无法通过公网访问,如果需要让其网站能够通过公网访问,只需要绑定前面创建的EIP即可。 第一步 如果弹性公网IP已经绑定了资源,需要先解绑 第二步 将私网CLB实例绑定到弹性公网IP …

CASAIM与东风日产达成治具开发设计与制造战略合作,共同推进3D打印和三维测量技术在汽车制造中的应用开发

CASAIM与东风日产是长期战略合作伙伴,近期,CASAIM中标东风日产的治具开发设计与制造项目,与东风日产在生产工具和工装治具达成战略合作,充分发挥双方技术优势,共同推进3D打印和三维测量技术在汽车制造中的应用开发和合…

用Python做生信分析--环境配置以哦见状

文章目录 pandas 模块安装方法查看pandas是否安装好,以及版本的查看 numpy 模块安装方法查看numpy是否安装好,以及版本的查看 biopython模块安装方法查看biopython是否安装好,以及版本的查看 jupyter-notebook(我比较喜欢用这个写…

AI产品经理 - 技术课-必须懂的技术

一、AI数据流向技术 1.实时智能调度 二、常用的算法 3.案例:自然语言生成NLG&语音识别 4.虚拟现实&机器学习平台 5.深度学习 5.决策管理系统&生物特征识别技术 6.机器人流程自动化& NLP(自然语言处理)

Springboot使用log4j2日志框架

文章目录 1.pom.xml引入依赖2.配置文件引入log4j2的配置文件3.导入log4j2配置文件4.通过Slf4j注解来使用log.info()等最后 1.pom.xml引入依赖 提示&#xff1a;lombok用于Slf4j注解 <dependency><groupId>org.springframework.boot</groupId><artifactId&…