上两节介绍了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. AJAX接口-拉购网职位搜索爬虫

    拉购网职位搜索爬虫 分析职位搜索调用接口: 浏览器开发者模式(快捷键F12)切换手机模式,打开拉购网职位搜索链接 https://m.lagou.com/search.html 输入搜索关键词, 例如 ...

  2. php 断点续传以及100% 后台zip解压

    前台部分 <div class="col-md-12"> <div class="form-group"> <label clas ...

  3. 最全总结 | 聊聊 Python 办公自动化之 Excel(下)

    1. 前言 前面谈到 Python 处理 Excel 文件最常见的两种方式,即:xlrd/xlwt.openpyxl ​其中, xlrd/xlwt 这一组合,xlrd 可以负责读取数据,而 xlwt ...

  4. hadoop之yarn(优化篇)

    最近一直在学习hadoop的一些原理和优化,然后也做了一些实践,也有没有去做实践的,反正个人观点都记录下来 一.yarn的介绍 YARN的基本结构由一个ResourceManager与多个NodeMa ...

  5. hibernate3.6-联合主键注解以及openSession和getCurrentSession区别

    [联合主键]>>>>配置方式:xml:    1. Student中单独创建StudentPk主键实体类 2. 配置: <composite-id name=" ...

  6. 经典c程序100例==11--20

    [程序11] 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月 后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 1.程序分析: 兔子的规律为数列1 ...

  7. redis重点ppt

  8. JVM初识

    先来看一张图 首先jvm是什么? jvm是java运行环境的一部分,是一种以软件模式虚拟出来的一个计算机系统. 如上图所示,JVM 主要分为三个子系统:类加载器.运行时数据区和执行引擎. 类加载器子系 ...

  9. kafka SASL认证介绍及自定义SASL PLAIN认证功能

    目录 kafka 2.x用户认证方式小结 SASL/PLAIN实例(配置及客户端) broker配置 客户端配置 自定义SASL/PLAIN认证(二次开发) kafka2新的callback接口介绍 ...

  10. 死磕以太坊源码分析之p2p节点发现

    死磕以太坊源码分析之p2p节点发现 在阅读节点发现源码之前必须要理解kadmilia算法,可以参考:KAD算法详解. 节点发现概述 节点发现,使本地节点得知其他节点的信息,进而加入到p2p网络中. 以 ...