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之变量和参数
Oct 10 Python
python实现将html表格转换成CSV文件的方法
Jun 28 Python
Python的Django框架可适配的各种数据库介绍
Jul 15 Python
python2.7 json 转换日期的处理的示例
Mar 07 Python
不到40行代码用Python实现一个简单的推荐系统
May 10 Python
解决Python3 抓取微信账单信息问题
Jul 19 Python
django项目用higcharts统计最近七天文章点击量
Aug 17 Python
Python基本语法之运算符功能与用法详解
Oct 22 Python
python生成特定分布数的实例
Dec 05 Python
Python matplotlib修改默认字体的操作
Mar 05 Python
深入浅析Python 命令行模块 Click
Mar 11 Python
python实现斗地主分牌洗牌
Jun 22 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
多数据表共用一个页的新闻发布
2006/10/09 PHP
php返回相对时间(如:20分钟前,3天前)的方法
2015/04/14 PHP
PHP开发实现微信退款功能示例
2017/11/25 PHP
PHP crc32()函数讲解
2019/02/14 PHP
javascript 图片上传预览-兼容标准
2009/06/01 Javascript
基于jquery实现的鼠标拖拽元素复制并写入效果
2011/08/23 Javascript
js数组转json并在后台对其解析具体实现
2013/11/20 Javascript
SuperSlide2实现图片滚动特效
2014/06/20 Javascript
javascript学习总结之js使用技巧
2015/09/02 Javascript
Three.js学习之文字形状及自定义形状
2016/08/01 Javascript
javascript实现用户点击数量统计
2016/12/25 Javascript
微信小程序实现锚点定位楼层跳跃的实例
2017/05/18 Javascript
vue使用jsonp抓取qq音乐数据的方法
2018/06/21 Javascript
基于layui数据表格以及传数据的方式
2018/08/19 Javascript
element-ui 中使用upload多文件上传只请求一次接口
2019/07/19 Javascript
原生js添加一个或多个类名的方法分析
2019/07/30 Javascript
vue实现分页加载效果
2019/12/24 Javascript
Vue3配置axios跨域实现过程解析
2020/11/25 Vue.js
[28:42]Ti4正赛VG vs NEWBEE1
2014/07/19 DOTA
[59:48]DOTA2-DPC中国联赛 正赛 VG vs Magma BO3 第一场 1月26日
2021/03/11 DOTA
python实现简单ftp客户端的方法
2015/06/28 Python
简单介绍Python的Django框架加载模版的方式
2015/07/20 Python
Python基于matplotlib实现绘制三维图形功能示例
2018/01/18 Python
详解Python3的TFTP文件传输
2018/06/26 Python
python实现维吉尼亚算法
2019/03/20 Python
python批量将excel内容进行翻译写入功能
2019/10/10 Python
Node.js 和 Python之间该选择哪个?
2020/08/05 Python
python利用faker库批量生成测试数据
2020/10/15 Python
html5的自定义data-*属性与jquery的data()方法的使用
2014/07/02 HTML / CSS
Aurora London官网:奢华、负担得起的皮革手袋
2020/08/01 全球购物
上班迟到检讨书
2014/01/10 职场文书
公益活动邀请函
2014/02/05 职场文书
《金钱的魔力》教学反思
2014/02/24 职场文书
使用numpy nonzero 找出非0元素
2021/05/14 Python
React forwardRef的使用方法及注意点
2021/06/13 Javascript
Vscode中SSH插件如何远程连接Linux
2022/05/02 Servers