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中用字符串调用函数或方法示例代码
Aug 04 Python
python验证码识别实例代码
Feb 03 Python
解决Pycharm出现的部分快捷键无效问题
Oct 22 Python
Python+OpenCV图片局部区域像素值处理改进版详解
Jan 23 Python
利用python开发app实战的方法
Jul 09 Python
PyQtGraph在pyqt中的应用及安装过程
Aug 04 Python
对Python获取屏幕截图的4种方法详解
Aug 27 Python
基于Python爬取51cto博客页面信息过程解析
Aug 25 Python
python实现图片素描效果
Sep 26 Python
python操作toml文件的示例代码
Nov 27 Python
python使用tkinter实现透明窗体上绘制随机出现的小球(实例代码)
May 17 Python
一劳永逸彻底解决pip install慢的办法
May 24 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
用PHP和ACCESS写聊天室(四)
2006/10/09 PHP
php基础教程 php内置函数实例教程
2012/08/21 PHP
laravel实现图片上传预览,及编辑时可更换图片,并实时变化的例子
2019/11/14 PHP
关于B/S判断浏览器断开的问题讨论
2008/10/29 Javascript
慎用 somefunction.prototype 分析
2009/06/02 Javascript
jquery应该如何来设置改变按钮input的onclick事件
2012/12/10 Javascript
js+css实现增加表单可用性之提示文字
2013/06/03 Javascript
jquery无刷新验证邮箱地址实现实例
2014/02/19 Javascript
JavaScript使用focus()设置焦点失败的解决方法
2014/09/03 Javascript
javascript实现简单的贪吃蛇游戏
2015/03/31 Javascript
js实现的二级横向菜单条实例
2015/08/22 Javascript
基于JavaScript实现生成名片、链接等二维码
2015/09/20 Javascript
AngularJS基础 ng-if 指令用法
2016/08/01 Javascript
js实现拖拽功能
2017/03/01 Javascript
jQuery validata插件实现方法
2017/06/25 jQuery
仿京东快报向上滚动的实例
2017/12/13 Javascript
小程序二次贝塞尔曲线实现购物车商品曲线飞入效果
2019/01/07 Javascript
python列表操作使用示例分享
2014/02/21 Python
Windows上使用virtualenv搭建Python+Flask开发环境
2016/06/07 Python
浅谈python中scipy.misc.logsumexp函数的运用场景
2016/06/23 Python
python3+PyQt5使用数据库表视图
2018/04/24 Python
python实现飞机大战微信小游戏
2020/03/21 Python
如何使用selenium和requests组合实现登录页面
2020/02/03 Python
Python selenium自动化测试模型图解
2020/04/15 Python
django序列化时使用外键的真实值操作
2020/07/15 Python
python 下载文件的几种方法汇总
2021/01/06 Python
COACH德国官方网站:纽约现代奢侈品牌,1941年
2018/06/09 全球购物
定制别致的瑜伽垫:Sugarmat
2019/06/21 全球购物
Nixon手表英国官网:美国尼克松手表品牌
2020/02/10 全球购物
HashMap和Hashtable的区别
2013/05/18 面试题
opencv实现图像平移效果
2021/03/24 Python
教育学习自我评价
2014/02/03 职场文书
出纳员岗位责任制
2014/02/11 职场文书
《生命 生命》教学反思
2014/04/19 职场文书
再读《皇帝的新衣》的读后感悟!
2019/08/07 职场文书
Java中Dijkstra(迪杰斯特拉)算法
2022/05/20 Java/Android