上两节介绍了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. 一步一步实现直播软件源码的RTMP推流流媒体服务

    第一步:准备工具 OBS推流工具下载及配置可以参见:OBS推流工具 第二步:安装流媒体服务 Windows/Linux系统环境中搭建直播流媒体服务 极速安装,下载解压一键启动即可,支持Windows和 ...

  2. JNI-从jvm源码分析Thread.interrupt的系统级别线程打断原理

    前言 在java编程中,我们经常会调用Thread.sleep()方法使得线程停止运行一段时间,而Thread类中也提供了interrupt方法供我们去主动打断一个线程.那么线程挂起和打断的本质究竟是 ...

  3. 【RabbitMQ-7】RabbitMQ—交换机标识符

    死信队列概念 死信队列(Dead Letter Exchange),死信交换器.当业务队列中的消息被拒绝或者过期或者超过队列的最大长度时,消息会被丢弃,但若是配置了死信队列,那么消息可以被重新发布到另 ...

  4. linux基本操作之linux登陆

    一 文本登陆方式: 输入用户名与密码:/etc/passwd文件对照(口令文件,保存基本的用户信息):/etc/shadow文件对照(影子文件,保存密码信息):启动相应的shell程序:用户得到 一个 ...

  5. python-redmine获取redmine平台的信息

    前言 最近做redmine的bug平台的分析,统计一些需要用到的数据,这里把相关调用的地方记录下来以备后用 相关的获取接口 #! /usr/bin/python # -*- coding:UTF-8 ...

  6. Mysql获取webshell方式总结

    select ... into outfile general_log cnblogs-MySQL获取webshell的几种方式 csdn-PhpMyadmin后台拿webshell方法总结

  7. pikachs 渗透测试1-环境及暴力破解

    一.安装 PhpStudy20180211,默认安装 1.mysql默认密码是root,因为在虚拟机,保留不动 2.解压pikachs 到 C:\phpStudy\PHPTutorial\WWW\pi ...

  8. msfconsle核心命令学习

    back 取消当前模块 banner check 检查当前exploit是否对目标有效,并不进行真正的攻击 color 禁用或启用输出是否包含颜色 connect 可以通过connect命令来链接Ne ...

  9. 通过ip访问项目

  10. 给力啊!这篇Spring Bean的依赖注入方式笔记总结真的到位,没见过写的这么细的

    1. Bean的依赖注入概念 依赖注入(Dependency Injection):它是 Spring 框架核心 IOC 的具体实现.在编写程序时,通过控制反转,把对象的创建交给了 Spring,但是 ...