Python如何定义接口和抽象类


Posted in Python onJuly 28, 2020

问题

你想定义一个接口或抽象类,并且通过执行类型检查来确保子类实现了某些特定的方法

解决方案

使用 abc 模块可以很轻松的定义抽象基类:

from abc import ABCMeta, abstractmethod

class IStream(metaclass=ABCMeta):
  @abstractmethod
  def read(self, maxbytes=-1):
    pass

  @abstractmethod
  def write(self, data):
    pass

抽象类的一个特点是它不能直接被实例化,比如你想像下面这样做是不行的:

a = IStream() # TypeError: Can't instantiate abstract class
        # IStream with abstract methods read, write

抽象类的目的就是让别的类继承它并实现特定的抽象方法:

class SocketStream(IStream):
  def read(self, maxbytes=-1):
    pass

  def write(self, data):
    pass

抽象基类的一个主要用途是在代码中检查某些类是否为特定类型,实现了特定接口:

def serialize(obj, stream):
  if not isinstance(stream, IStream):
    raise TypeError('Expected an IStream')
  pass

除了继承这种方式外,还可以通过注册方式来让某个类实现抽象基类:

import io

# Register the built-in I/O classes as supporting our interface
IStream.register(io.IOBase)

# Open a normal file and type check
f = open('foo.txt')
isinstance(f, IStream) # Returns True

@abstractmethod 还能注解静态方法、类方法和 properties 。 你只需保证这个注解紧靠在函数定义前即可:

class A(metaclass=ABCMeta):
  @property
  @abstractmethod
  def name(self):
    pass

  @name.setter
  @abstractmethod
  def name(self, value):
    pass

  @classmethod
  @abstractmethod
  def method1(cls):
    pass

  @staticmethod
  @abstractmethod
  def method2():
    pass

讨论

标准库中有很多用到抽象基类的地方。collections 模块定义了很多跟容器和迭代器(序列、映射、集合等)有关的抽象基类。 numbers 库定义了跟数字对象(整数、浮点数、有理数等)有关的基类。io 库定义了很多跟I/O操作相关的基类。

你可以使用预定义的抽象类来执行更通用的类型检查,例如:

import collections

# Check if x is a sequence
if isinstance(x, collections.Sequence):
...

# Check if x is iterable
if isinstance(x, collections.Iterable):
...

# Check if x has a size
if isinstance(x, collections.Sized):
...

# Check if x is a mapping
if isinstance(x, collections.Mapping):

尽管ABCs可以让我们很方便的做类型检查,但是我们在代码中最好不要过多的使用它。 因为Python的本质是一门动态编程语言,其目的就是给你更多灵活性, 强制类型检查或让你代码变得更复杂,这样做无异于舍本求末。

以上就是Python如何定义接口和抽象类的详细内容,更多关于Python定义接口和抽象类的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
Python HTMLParser模块解析html获取url实例
Apr 08 Python
python实现爬虫统计学校BBS男女比例(一)
Dec 31 Python
python相似模块用例
Mar 04 Python
Django权限机制实现代码详解
Feb 05 Python
学习python中matplotlib绘图设置坐标轴刻度、文本
Feb 07 Python
python导入pandas具体步骤方法
Jun 23 Python
pyqt5 键盘监听按下enter 就登陆的实例
Jun 25 Python
Python 3.8正式发布重要新功能一览
Oct 17 Python
python实现把两个二维array叠加成三维array示例
Nov 29 Python
PyCharm 专业版安装图文教程
Feb 20 Python
pandas 数据类型转换的实现
Dec 29 Python
Python面试不修改数组找出重复的数字
May 20 Python
Python爬虫之爬取淘女郎照片示例详解
Jul 28 #Python
Python selenium键盘鼠标事件实现过程详解
Jul 28 #Python
用python写爬虫简单吗
Jul 28 #Python
公认8个效率最高的爬虫框架
Jul 28 #Python
python如何爬取网页中的文字
Jul 28 #Python
Python同时处理多个异常的方法
Jul 28 #Python
Python远程方法调用实现过程解析
Jul 28 #Python
You might like
PHPThumb PHP 图片缩略图库
2012/03/11 PHP
php打造智能化的柱状图程序,用于报表等
2015/06/19 PHP
PHP创建/删除/复制文件夹、文件
2016/05/03 PHP
thinkPHP5.0框架验证码调用及点击图片刷新简单实现方法
2018/09/07 PHP
JS连连看源码完美注释版(推荐)
2013/12/09 Javascript
html5+javascript制作简易画板附图
2014/04/25 Javascript
让javascript加载速度倍增的方法(解决JS加载速度慢的问题)
2014/12/12 Javascript
JS+CSS实现仿msn风格选项卡效果代码
2015/10/22 Javascript
学习javascript面向对象 理解javascript原型和原型链
2016/01/04 Javascript
浅谈JavaScript 浏览器对象
2016/06/03 Javascript
微信小程序 教程之wxapp 视图容器 view
2016/10/19 Javascript
深入理解React高阶组件
2017/09/28 Javascript
写一个Vue Popup组件
2019/02/25 Javascript
vue实现鼠标移入移出事件代码实例
2019/03/27 Javascript
vue实现倒计时获取验证码效果
2020/04/17 Javascript
[03:31]DOTA2英雄基础教程 大地之灵
2013/12/17 DOTA
Python HTMLParser模块解析html获取url实例
2015/04/08 Python
KMP算法精解及其Python版的代码示例
2016/06/01 Python
Python实现数据库并行读取和写入实例
2017/06/09 Python
基于Python对象引用、可变性和垃圾回收详解
2017/08/21 Python
django实现用户登陆功能详解
2017/12/11 Python
Python制作词云的方法
2018/01/03 Python
python unittest实现api自动化测试
2018/04/04 Python
Python自动化之数据驱动让你的脚本简洁10倍【推荐】
2019/06/04 Python
python判断文件夹内是否存在指定后缀文件的实例
2019/06/10 Python
python3用PIL把图片转换为RGB图片的实例
2019/07/04 Python
python中的RSA加密与解密实例解析
2019/11/18 Python
Python tkinter常用操作代码实例
2020/01/03 Python
Python3中小括号()、中括号[]、花括号{}的区别详解
2020/11/15 Python
UGG雪地靴德国官网:UGG德国
2016/11/19 全球购物
The North Face北面荷兰官网:美国著名户外品牌
2019/10/16 全球购物
少先队入队活动方案
2014/02/08 职场文书
培训专员岗位职责
2014/02/26 职场文书
夫妻忠诚协议书范本
2014/11/17 职场文书
垂直极限观后感
2015/06/08 职场文书
vue组件vue-esign实现电子签名
2022/04/21 Vue.js