上两节介绍了Python抽象类的真实子类的定义和使用,本节介绍另一种抽象类的实现方法:虚拟子类方法。

一、    相关概念

虚拟子类是将其他的不是从抽象基类派生的类”注册“到抽象基类,让Python解释器将该类作为抽象基类的子类使用,因此称为虚拟子类,这样第三方类不需要直接继承自抽象基类。注册的虚拟子类不论是否实现抽象基类中的抽象内容,Python都认为它是抽象基类的子类,调用 issubclass(子类,抽象基类),isinstance (子类对象,抽象基类)都会返回True。

  这种通过注册增加虚拟子类是抽象基类动态性的体现,也是符合Python风格的方式。它允许我们动态地,清晰地改变类的属别关系。当一个类继承自抽象基类时,该类必须完成抽象基类定义的语义;当一个类注册为虚拟子类时,这种限制则不再有约束力,可以由程序开发人员自己约束自己,因此提供了更好的灵活性与扩展性(当然也带来了一些意外的问题)。这种能力在框架程序使用第三方插件时,采用虚拟子类即可以明晰接口,只要第三方插件能够提供框架程序要求的接口,不管其类型是什么,都可以使用抽象基类去调用相关能力,又不会影响框架程序去兼容外部接口的内部实现。老猿认为,从某种程度上讲,虚拟子类这种模式,是在继承这种模式下的一种多态实现。

二、    语法

1.    虚拟子类定义的前面步骤都与真实子类相同,首先都是import  abc 模块,然后定义抽象基类;

2.    定义子类;

3.    将子类注册为抽象基类的虚拟子类,语法为:

基类名. register(子类名)三、    例子说明

1、    以上节的Shape类为例,定义抽象基类

from abc import ABC, abstractmethod

class Shape(ABC):
    @abstractmethod
    def getArea():pass  #定义获取面积的抽象方法
    
    @abstractmethod
    def getGirth():pass  #定义获取周长的抽象方法

2、    定义非Shape派生类

class House():
     def __init__(self,area):self.area=area
     def showArea(self):return self.area

3、    将House类注册为Shape的子类

Shape.register(House)

4、    定义House类实例化变量

house=House(100)

5、    查看House类是否为Shape子类,实例house是否为Shape的实例

issubclass(House,Shape)
isinstance(house,Shape)

四、    执行代码及截图

#coding:utf-8
#抽象类虚拟子类 from abc import ABC, abstractmethod class Shape(ABC):
    @abstractmethod
    def getArea():pass  #定义获取面积的抽象方法
    
class House():
     def __init__(self,area):self.area=area
     def showArea(self):return self.area
      
Shape.register(House)
issubclass(House,Shape)
house=House(100)
isinstance(house,Shape)
house.getArea()#执行报错,没有该方法 class House():#调整类定义,将showArea方法改成getArea
     def __init__(self,area):self.area=area
     def getArea(self):return self.area issubclass(House,Shape)#由于类重新定义,该函数应该返回False
Shape.register(House)#重新注册虚拟子类 house=House(100)#重新定义变量:
issubclass(House,Shape)
isinstance(house,Shape)



本节结合案例详细介绍了通过子类注册到抽象基类的方式实现虚拟子类的方法,注册虚拟子类无需子类实现抽象基类的所有抽象方法,在某些特定场景下非常有用。

老猿Python(https://blog.csdn.net/LaoYuanPython)系列文章用于逐步介绍老猿学习Python后总结的学习经验,这些经验有助于没有接触过Python的程序员可以很容易地进入Python的世界。

欢迎大家批评指正,谢谢大家关注!

第7.21节 Python抽象类—register注册虚拟子类的更多相关文章

  1. python之抽象类&abc模块+虚拟子类&register

    抽象类和接口: java 我们先从java讲起,没有java基础的可以略过. (挖坑) python 在python并没有抽象类之说,或者说抽象类=接口类(区别于接口) 继承有两种用途: 一:继承基类 ...

  2. 第11.21节 Python 中正则表达式的其他扩展功能

    一. 引言 在<第11.17节 Python 正则表达式扩展功能:命名组功能及组的反向引用>中老猿介绍了组匹配模式的命名组功能及引用组功能,这两者都是正则表达式的扩展功能,其实在re模块中 ...

  3. 第8.21节 Python中__lt__、__gt__等 “富比较”(“rich comparison”)方法用途探究

    一. 富比较方法 Python的基类object提供一系列可以用于实现同类对象进行"比较"的方法,可以用于同类对象的不同实例进行比较.他们也是实例方法,定义如下: object.l ...

  4. 第8.22节 Python案例详解:重写 “富比较”方法控制比较逻辑

    一. 案例说明 本节定义一个小汽车的类Car,类中包括车名carname.百公里油耗oilcostper100km.价格price三个属性.然后实现__lt__.__gt__.__le__.__ge_ ...

  5. 第8.23节 Python中使用sort/sorted排序与“富比较”方法的关系分析

    一. 引言 <第8.21节 Python中__lt__.gt__等 "富比较"("rich comparison")方法用途探究>和<第8.2 ...

  6. 第7.20节 案例详解:Python抽象类之真实子类

    第7.20节 案例详解:Python抽象类之真实子类 上节介绍了Python抽象基类相关概念,并介绍了抽象基类实现真实子类的步骤和语法,本节结合一个案例进一步详细介绍. 一.    案例说明 本节定义 ...

  7. 第7.19节 Python中的抽象类详解:abstractmethod、abc与真实子类

    第7.19节 Python中的抽象类详解:abstractmethod.abc与真实子类 一.    引言 前面相关的章节已经介绍过,Python中定义某种类型是以实现了该类型对应的协议为标准的,而不 ...

  8. Python抽象类以及元类

    抽象基类: 继承的约束与协议 __doc__ = """ 抽象基类: 继承的约束与协议 # 抽象基类 --- 有点java的味道,也有点golang的味道,继承,协议,接 ...

  9. 8 python 抽象类

    1.抽象类 --类似接口 接口的概念: 自己提供给使用者来调用自己功能的方式\方法\入口, 1.1.java中接口  interface =================第一部分:Java 语言中的 ...

随机推荐

  1. 一款基于.NET Core的认证授权解决方案-葫芦藤1.0开源啦

    背景 18年公司准备在技术上进行转型,而公司技术团队是互相独立的,新技术的推动阻力很大.我们需要找到一个切入点.公司的项目很多,而各个系统之间又不互通,导致每套系统都有一套登录体系,给员工和客户都带来 ...

  2. flex与bison的学习

    获取bison http://www.gnu.org/software/bison 获取flex http://flex.sourceforge.net/ 本书的范例 ftp://ftp.iecc.c ...

  3. 视频直播源码开发中的流媒体协议:rtmp协议

    一.概念与摘要 视频直播源码的RTMP协议从属于应用层,被设计用来在适合的传输协议(如TCP)上复用和打包多媒体传输流(如音频.视频和互动内容).RTMP提供了一套全双工的可靠的多路复用消息服务,类似 ...

  4. Python中列表逆序

    1.list.reverse() 该方法是直接在原来的列表里面将元素进行逆序排列,不需要创建新的副本用于存储结果. 这种方式,有好处也有坏处.好处是节省内存使用,因为我们不需要重新申请空间来保存最后的 ...

  5. Golang 接口型函数和http.Handler接口

    一.接口型函数 参考Golang必备技巧:接口型函数 1.原始接口实现 type Handler interface { Do(k, v interface{}) } func Each(m map[ ...

  6. HotSpot源码分析之C++对象的内存布局

    HotSpot采用了OOP-Klass模型来描述Java类和对象.OOP(Ordinary Object Pointer)指的是普通对象指针,而Klass用来描述对象的具体类型.为了更好理解这个模型, ...

  7. spring的原理

    一.pring的原理 1.1 IOC控制反转 ==> 扫描机制通过代理方式动态创建对象 扫描注解,通过反射获取类路径,动态创建对应类的对象,放置在对象池中(多线程做法,防止短时间内创建对象过多, ...

  8. ceph luminous 新功能之内置dashboard

    前言 ceph luminous版本新增加了很多有意思的功能,这个也是一个长期支持版本,所以这些新功能的特性还是很值得期待的,从底层的存储改造,消息方式的改变,以及一些之前未实现的功能的完成,都让ce ...

  9. asp.net core 使用 TestServer 来做集成测试

    asp.net core 使用 TestServer 来做集成测试 Intro 之前我的项目里的集成测试是随机一个端口,每次都真实的启动一个 WebServer,之前也有看到过微软文档上 TestSe ...

  10. DevOps,你真的了解吗?

    与大数据和PRISM(NSA的监控项目之一),DevOps(开发运维)如今是科技人士挂在嘴边的热词,但遗憾的是,类似圣经,每个人都引用DevOps的只言片语,但真正理解并能执行的人极少.根据CA的一项 ...