抽象基类(abc模块)

  • 介绍
  • 白话理解
  • 实用场景

介绍

该模块提供了一个元类 ABCMeta,可以用来定义抽象类,另外还提供一个工具类 ABC,可以用它以继承的方式定义抽象基类。

装饰器以“@”标识,实质上是一层包裹函数,即函数的函数。写在函数定义( def 语句)的前面,表示 def 语句后定义的函数受到装饰器的装饰。

ABC(抽象基类),主要定义了基本类和最基本的抽象方法,可以为子类定义共有的API,不需要具体实现。

abc模块,Python 对于ABC的支持模块,定义了一个特殊的metaclass:ABCMeta 还有一些装饰器:@abstractmethod 和 @abstarctproperty 。

**抽象基类可以不实现具体的方法(当然也可以实现,只不过子类如果想调用抽象基类中定义的接口需要使用super())而是将其留给派生类实现。**抽象基类可以被子类直接继承,也可以将其他的类”注册“(register)到其门下当虚拟子类,虚拟子类的好处是你实现的第三方子类不需要直接继承自基类但是仍然可以声称自己子类中的方法实现了基类规定的接口(issubclass(), issubinstance())!

虚拟子类是通过调用metaclass是 abc.ABCMeta 的抽象基类的 register 方法注册到抽象基类门下的,可以实现抽象基类中的部分API接口,也可以根本不实现,但是issubclass(), issubinstance()进行判断时仍然返回真值。

直接继承抽象基类的子类就没有这么灵活,在metaclass是 abc.ABCMeta的抽象基类中可以声明”抽象方法“和“抽象属性”,直接继承自抽象基类的子类虽然判断issubclass()时为真,但只有完全覆写(实现)了抽象基类中的“抽象”内容后,才能被实例化,而通过注册的虚拟子类则不受此影响。

metaclass为 abc.ABCMeta 的抽象基类如果想要声明“抽象方法”,可以使用abc模块中的装饰器 @abstractmethod ,如果想声明“抽象属性”,可以使用abc模块中的 @abstractproperty 。

最后,为什么要提six模块呢,six模块是Python为了兼容Python 2.x 和Python 3.x提供的一个模块,该模块中有一个针对类的装饰器 @six.add_metaclass(MetaClass) 可以为两个版本的Python类方便地添加metaclass。这样我们就可以同时利用Python中的abc模块和six模块在类的定义前添加 @six.add_metaclass(abc.ABCMeta) 来优雅地声明一个抽象基础类了!

从理论层面打通了,下面上代码,首先看一下类装饰器 @six.add_metaclass(MetaClass) 的用法,在下面的代码中,我们希望声明类 MyClass 的metaclass是类 Meta ,注意类 Meta 需要是一个metaclass。

import six@six.add_metaclass(Meta)
class MyClass(object):pass

在Python 3 等价于

import sixclass MyClass(object, metaclass = Meta):pass

在Python 2.x (x >= 6)中等价于

import sixclass MyClass(object):__metaclass__ = Metapass

或者直接用引入装饰器的目的:

import sixclass MyClass(object):pass
MyClass  = six.add_metaclass(Meta)(MyClass)

类装饰器 @six.add_metaclass(MetaClass) 的作用是在不同版本的Python之间提供一个优雅的声明类的metaclass的手段,事实上不用它也可以,只是使用了它代码更为整洁明了。

下面结合一个特殊的metaclass即 abc.ABCMeta 来看一段代码:

import abc
import six@six.add_metaclass(abc.ABCMeta)
class PluginBase(object):@abc.abstractmethoddef func_a(self,data):"""an abstract method need to be implemented"""@abc.abstractmethoddef func_b(self,output, data):"""another abstract method need to be implemented"""class RegisteredImplementation(object):def func_c(self, data):print "Method in third-party class, "+ str(data)class SubclassImplementation(PluginBase):def func_a(self,data):print "Overriding func_a, "+ str(data)def func_b(self,data):print "Overriding func_b, "+ str(data)def func_d(self, data):print dataPluginBase.register(RegisteredImplementation)if __name__=='__main__':for sc in PluginBase.__subclasses__():print "subclass of PluginBase: " + sc.__name__print("")print issubclass(RegisteredImplementation, PluginBase)print isinstance(RegisteredImplementation(), PluginBase)print issubclass(SubclassImplementation, PluginBase)print("")obj1 = RegisteredImplementation()obj1.func_c("It's right!")print("")obj2 = SubclassImplementation()obj2.func_a("It's right!")print ""

上面这端代码的含义是:

声明一个metaclass是 abc.ABCMeta 的抽象基类 PluginBase ,为其定义两个抽象方法,等待派生类的实现。接着定义了一个第三方类 RegisterdImplementation ,将其注册为类 PluginBase 的虚拟子类。再定义一个子类 SubclassImplementation 直接继承自抽象基类 PluginBase 。

接着进行试验,运行结果如下:

subclass of PluginBase: SubclassImplementationTrue
True
TrueMethod in third-party class, It's right!Overriding func_a, It's right!

从运行的结果我们可以看出:

**虚拟子类不算做直接继承子类,因此可以不实现抽象基类 PluginBase 的任何方法;**但直接继承的子类 SubclassImplementation 必须完全实现抽象基类的抽象方法才能够实例化(这里可以注释掉 26 - 30 行的代码实验)。

同时,不论是虚拟子类还是直接继承子类,issubclass()和issubinstance()判断他们与抽象基类的关系时都返回真值。

白话理解

按照我自己的理解就是,抽象基类是一种“主要规则”,而继承他的子类是“其他规则”,第三方子类就相当于是“从其他地方引入的规则”。也就是想要完成这个项目,首先要满足主要规则,主要规则可以是空头规则,也可以是举办方拟定好的规则,各个小组进行项目必须遵守(抽象基类可以不实现具体的方法(当然也可以实现,只不过子类如果想调用抽象基类中定义的接口需要使用super())而是将其留给派生类实现。)。如果是空头,就由各个小组自定义内容;如果定好了,就需要使用super()。第三方规则是引入的规则,只要引入进来,完成项目就要遵守它,(issubclass()和issubinstance()判断他们与抽象基类的关系时都返回真值。)但这个引入的规则并非为本项目小组的原创,不拘泥于“主要规则”(虚拟子类不算做直接继承子类,因此可以不实现抽象基类 PluginBase 的任何方法)。

实用场景

1. 我们去检查某个类是否具有某个方法

class Animal(object):def __init__(self,list_1):self.list_1 =  list_1def __len__(self):return len(self.list_1)an = Animal(["Dog","Cat"])
print(hasattr(an,"__len__"))# 返回的是布尔值,用来判断类中是否包含指定方法

在某些情况下判定某个对象的类型

from collection.abc import Sized
print(isinstance(an,Sized))

2. 强制某个子类必须实现某些方法
需要设计一个抽象基类,指定子类必须实现某些方法


Python装饰器、metaclass、abc模块学习笔记
abc — 抽象基类
4-2 抽象基类(abc模块) - 1 .mp4

Python:抽象基类(abc模块)相关推荐

  1. python abc模块_3-2 抽象基类abc模块

    abc ---- Abstract base class 何为抽象基类: 类比JAVA: 可以当作是JAVA中的接口,在JAVA里面它是无法实现多继承的,JAVA只能继承一个类,但是JAVA可以继承多 ...

  2. python3 抽象基类 abc.abstractmethod

    python3 抽象基类 abc.abstractmethod 有时,我们抽象出一个基类,知道要有哪些方法,但只是抽象方法,并不实现功能,只能继承, 而不能被实例化,但子类必须要实现该方法.看下面的例 ...

  3. python抽象基类的作用_Python:多态、鸭子模型和抽象基类

    1. 多态 什么是多态 -- 多态,指的是一种事务具有多种形态: -- python是一种动态语言,默认支持多态,同一个方法 调用 不同的类对象 ,执行的 结果各不相同: 多态实现 -- 继承:不同子 ...

  4. python 抽象基类_python3 抽象基类

    1,抽象基类(Abstract base class或者 ABCs)用于 定义一组必须被类的"鸭子类型"实例实现的方法与属性,可以继承抽象基类本身的类作为类的实例,但是必须提供所有 ...

  5. c++------------之---【虚函数和抽象基类的应用】

    /*************************************************************************************************** ...

  6. Python高级:了解Python ABC(抽象基类)及 应用场景

    ABC,Abstract Base Class(抽象基类),主要定义了基本类和最基本的抽象方法,可以为子类定义共有的API,不需要具体实现.相当于是Java中的接口或者是抽象类. 抽象基类可以不实现具 ...

  7. Python ABC(抽象基类)

    轉自:https://blog.csdn.net/qijiqiguai/article/details/77269839 ABC(Abstract Base Class抽象基类)主要定义了不需要具体实 ...

  8. python虚函数_Python进阶话题杂谈(十三)纯虚函数与抽象基类

    纯虚函数与抽象类都是Python面向对象中重要的编程范式,用于对继承类做强制性接口实现约定. abc模块包含了一系列与抽象基类与纯虚函数相关的方法.Python中通过修改元类进行抽象基类的设定.这里P ...

  9. python类方法和实例方法syntax errors_《Fluent Python》CH.11_面向对象_接口:从协议到抽象基类...

    主要内容 首先,本章说明抽象基类的常见用途:实现接口时作为超类使用 说明抽象基类如何检查具体子类是否符合接口定义,以及如何使 用注册机制声明一个类实现了某个接口,而不进行子类化操作 最后, 说明如何让 ...

最新文章

  1. oracle有一百个人围一圈报数,案例:Oracle创建表时报session超过最大值 ORA-00018 证明递归ses...
  2. 从前端界面开发谈微信小程序体验
  3. nik collection滤镜
  4. 51单片机mysql_51单片机的定时器
  5. 使用Spring-Retry重试处理
  6. shell 特殊符号
  7. Microsoft Visual Studio Web 创作组件安装失败的解决方法
  8. mysql explain desc_MySQL中EXPLAIN结果的参数详解
  9. 图书管理系统数据库设计实验报告
  10. CSDN博客排版格式入门
  11. 漂亮特殊字体可复制_特殊字体生成器 漂亮特殊字体可复制
  12. [编程神域 C语言浮游塔 第①期] Hello C language world
  13. 如何在WPF中使用Winform控件
  14. mysql logs_MySQL Logs
  15. [BUU刷题记录]day01-起步
  16. 旧书网购_基于旧书的新工作簿
  17. android popmenu,android 自定义PopupMenu详解
  18. retrofit源码,这篇文章可以满足你80%日常工作!重难点整理
  19. 财政部及汇金承诺全额认购工行配股
  20. 关于图片webp 转 jpg

热门文章

  1. Github标星5.3K,进阶学习工作最全指南
  2. 视频号扩展链接怎样添加
  3. Linux内核TSS的使用
  4. parallel的一个小坑
  5. SpiderFlow平台v0.3.0初次使用并爬取薄荷网的热量和减法功效
  6. CoffeeScript - CoffeeScript安装使用入门
  7. 【导航】自己的导航网站
  8. 新手如何做好百度推广?
  9. 家国梦自动收取金币、货物、升级建筑、拆相册等脚本
  10. 一分钟了解Java Attach机制