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抓取某汽车网数据解析html存入excel示例
Dec 04 Python
Python yield 小结和实例
Apr 25 Python
Python pickle模块用法实例分析
May 27 Python
python 实现对文件夹内的文件排序编号
Apr 12 Python
详解利用django中间件django.middleware.csrf.CsrfViewMiddleware防止csrf攻击
Oct 09 Python
Python基础之条件控制操作示例【if语句】
Mar 23 Python
Python3.5 Pandas模块之DataFrame用法实例分析
Apr 23 Python
Python3.5常见内置方法参数用法实例详解
Apr 29 Python
python切片(获取一个子列表(数组))详解
Aug 09 Python
python plotly画柱状图代码实例
Dec 13 Python
基于Python实现简单学生管理系统
Jul 24 Python
python3:excel操作之读取数据并返回字典 + 写入的案例
Sep 01 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 Header用于页面跳转要注意的几个问题总结
2008/10/03 PHP
php中日期加减法运算实现代码
2011/12/08 PHP
PHP处理Oracle的CLOB实例
2014/11/03 PHP
php结合正则批量抓取网页中邮箱地址
2015/05/19 PHP
读jQuery之十一 添加事件核心方法
2011/07/31 Javascript
如何阻止复制剪切和粘贴事件为了表单内容的安全
2013/05/23 Javascript
jQuery插件pagewalkthrough实现引导页效果
2015/07/05 Javascript
javascript图片切换综合实例(循环切换、顺序切换)
2016/01/13 Javascript
关于获取DIV内部内容报错的原因分析及解决办法
2016/01/29 Javascript
JavaScript代码性能优化总结篇
2016/05/15 Javascript
Angular 2应用的8个主要构造块有哪些
2016/10/17 Javascript
微信小程序之拖拽排序(代码分享)
2017/01/21 Javascript
基于nodejs+express4.X实现文件下载的实例代码
2017/07/13 NodeJs
vue-router路由与页面间导航实例解析
2017/11/07 Javascript
Node.js笔记之process模块解读
2018/05/31 Javascript
JS事件绑定的常用方式实例总结
2019/03/02 Javascript
JS+HTML5本地存储Localstorage实现注册登录及验证功能示例
2020/02/10 Javascript
Javascript操作select控件代码实例
2020/02/14 Javascript
JavaScript Tab菜单实现过程解析
2020/05/13 Javascript
Python入门篇之面向对象
2014/10/20 Python
selenium+python实现自动登录脚本
2018/04/22 Python
Python 批量合并多个txt文件的实例讲解
2018/05/08 Python
Django中的forms组件实例详解
2018/11/08 Python
Python标准库使用OrderedDict类的实例讲解
2019/02/14 Python
对python借助百度云API对评论进行观点抽取的方法详解
2019/02/21 Python
一个可以套路别人的python小程序实例代码
2019/04/09 Python
基于python和flask实现http接口过程解析
2020/06/15 Python
Python基于xlutils修改表格内容过程解析
2020/07/28 Python
tensorflow2.0教程之Keras快速入门
2021/02/20 Python
JSF面试题:Jsf中导航的标签是什么
2013/04/20 面试题
党支部公开承诺书
2014/03/28 职场文书
债务追讨授权委托书范本
2014/10/16 职场文书
小学二年级班主任工作经验交流材料
2015/11/02 职场文书
导游词之杭州岳王庙
2019/11/13 职场文书
Nginx 502 Bad Gateway错误原因及解决方案
2021/03/31 Servers
MySQL之MyISAM存储引擎的非聚簇索引详解
2022/03/03 MySQL