python abc模块_3-2 抽象基类abc模块
abc ---- Abstract base class
何为抽象基类:
类比JAVA: 可以当作是JAVA中的接口,在JAVA里面它是无法实现多继承的,JAVA只能继承一个类,但是JAVA可以继承多个接口,而接口是无法实例化的,所以说在python里面它的抽象基类也是不可以实例化的。
注意:
我们需要明白一点的就是,python它是动态语言,动态语言他是没有变量的类型的(就是在声明变量是不用 char, int ...什么的),实际上在python中变量它只是一个符号而已,它可以指向任何类型的对象,所以说在python当中,也就不存在有多态的这一个概念。(我们可以赋值任何数据给我们的变量,而且它是可以修改。)
所以说它就不需要像JAVA那样去实现一个多态,出于语言本身的层面上来讲它原本就是支持多态的一个语言。
动态语言和静态语言最大的区别在于:
动态语言不需要要指明变量的类型,所以说动态语言就少了一个编译时检查错误的环境,在python中如果写错了代码实际上是很难知道的,只有在运行的时候才能发现错误,这也是动态语言共有的缺陷。
python信奉的是鸭子类型
鸭子类型贯穿python的面向对象当中,我们在使用python或是在设计python类的时候,我们都一定要把鸭子类型放在第一位。
上节课回顾:
它和java最大的区别是我们去实现一个class的时候我们是不需要继承指定的类型的。(不要把他们两混为一谈)
因为本身鸭子类型就是动态语言设计时候的一种非常好的一种理念,鸭子类型和我们的魔法函数实际上构成了我们python语言的基础也就是python里面的一种协议,因为python本身不是去通过继承某一个类或者接口就有某些特性,而是只要去实现某些指定的魔法函数,我们的类就是某种类型的对象。
那抽象基类是什么个说法?
答:
(1)在这个基础的类当中我们去设定好一些方法,然后所有的继承这个基类的类它都必须要覆盖这里面的方法。
(2)抽象基类是无法用来实例化的
疑问:既然python是基于鸭子类型去设计的,那为什么又多出抽象基类这个概念呢,我们直接去实现某个方法不就行了嘛?
我们假设两种用场景:
(1):我们去检查某个某个类是否有某种方法时
class Company:
def __init__(self, employee_list):
self.employee = employee_list
def __getitem__(self, item):
return self.employee[item]
def __str__(self):
return '-'.join(self.employee)
def __len__(self):
return len(self.employee)
com = Company(['abc', 'cvb'])
# 一般我们知道有hassattr可以判断。
#print(hasattr(com,'__len__')) # -- True
# 使用抽象接口判断
from collections.abc import Sized
print(isinstance(com, Sized))
补充说明:
根据我们的知识,isinstance是用来判断一个对象的实例,Company都没有继承与Sized,为什么能够正确返回True呢,这就由于python的设计,还是回到鸭子类型这边,基于isinstance函数在python内部的查找优化,以及查找方法(这些我都不会妈个蛋, 是python内部的一些实现方法,不过Sized我可以说明一下)。
我们从collections.abc中导入了Sized的抽象基类,源码瞄一眼:
class Sized(metaclass=ABCMeta):
__slots__ = ()
@abstractmethod
def __len__(self):
return 0
@classmethod
def __subclasshook__(cls, C):
if cls is Sized:
return _check_methods(C, "__len__")
return NotImplemented
解释:
这个Size的抽象基类,有个metaclass=ABCMeta这样的一个标注(别问,这是一种规定的写法他们是抽象基类的写法),我们可以看到他的@abstractmethod 抽象方法(该装饰器,在中abc导入:from abc import abstractmethod), 关键判断它是否有__len__方法在于下面的__subclasshook__魔法函数,(这个函数里面的_check_methods起了关判断作用)
小结
综上述也就不难说明为什么isinstance(com, Sized)返回True了。
我们来看第二个场景:
我们需要强制某个子类必须实现某些方法(实现一个web框架,继承cache(redis, cache, memorychache),需要设计一个抽象基类,指定子类必须实现某些方法),做一些接口的强制规定
class Cache(object):
def set(self, key, value):
raise NotImplementedError # not Implemented Error ---> 未实现错误
def get(self, key):
raise NotImplementedError
# 用户在重写时需要覆盖带这个方法
class MyCache(Cache):
pass
mycache = MyCache()
mycache.get('ke', 'sv')
第一种情况我们在基类规定的方法中抛异常,如果子类不重写这个方法直接调用基类的方法则会报错,这是一种解决方案,弊端在于要在调用时才能发现错误,而不是在声明对象实例时。
让我们来定义一个抽象基类来解决这个问题
from abc import abstractmethod
from abc import ABCMeta
class Cache(metaclass=ABCMeta):
@abstractmethod
def set(self, key, value):
pass
@abstractmethod
def get(self, key):
pass
# 用户在重写时需要覆盖带这个方法
class MyCache(Cache):
pass
mycache = MyCache()
直接运行看结果:
直接在我们声明实例对象时就给报错了,需要我们在子类中重写这两个方法才行,我们看重写后的结果。
from abc import abstractmethod
from abc import ABCMeta
class Cache(metaclass=ABCMeta):
@abstractmethod
def set(self, key, value):
pass
@abstractmethod
def get(self, key):
pass
# 用户在重写时需要覆盖带这个方法
class MyCache(Cache):
def set(self, key, value):
print('sb')
def get(self, key):
print('rz')
mycache = MyCache()
结果是能够正确的声明变量。
总结
说出来你可能不信,上面的abc抽象基类其实在实际编写的时候是不提倡的,也不提倡使用多继承,我们后面会学习一种设计模式Mixin的设计模式,用于增强丰富对象的功能。
上面的abc, collection.abc 中提供许多抽象基类,其实它更像是一个文档,带我们去了解python。
python abc模块_3-2 抽象基类abc模块相关推荐
- python3 抽象基类 abc.abstractmethod
python3 抽象基类 abc.abstractmethod 有时,我们抽象出一个基类,知道要有哪些方法,但只是抽象方法,并不实现功能,只能继承, 而不能被实例化,但子类必须要实现该方法.看下面的例 ...
- Python:抽象基类(abc模块)
抽象基类(abc模块) 介绍 白话理解 实用场景 介绍 该模块提供了一个元类 ABCMeta,可以用来定义抽象类,另外还提供一个工具类 ABC,可以用它以继承的方式定义抽象基类. 装饰器以" ...
- Python高级:了解Python ABC(抽象基类)及 应用场景
ABC,Abstract Base Class(抽象基类),主要定义了基本类和最基本的抽象方法,可以为子类定义共有的API,不需要具体实现.相当于是Java中的接口或者是抽象类. 抽象基类可以不实现具 ...
- python类方法和实例方法syntax errors_《Fluent Python》CH.11_面向对象_接口:从协议到抽象基类...
主要内容 首先,本章说明抽象基类的常见用途:实现接口时作为超类使用 说明抽象基类如何检查具体子类是否符合接口定义,以及如何使 用注册机制声明一个类实现了某个接口,而不进行子类化操作 最后, 说明如何让 ...
- Python学习笔记28:从协议到抽象基类
Python学习笔记28:从协议到抽象基类 今后本系列笔记的示例代码都将存放在Github项目:https://github.com/icexmoon/python-learning-notes 在P ...
- c++------------之---【虚函数和抽象基类的应用】
/*************************************************************************************************** ...
- Python ABC(抽象基类)
轉自:https://blog.csdn.net/qijiqiguai/article/details/77269839 ABC(Abstract Base Class抽象基类)主要定义了不需要具体实 ...
- python虚函数_Python进阶话题杂谈(十三)纯虚函数与抽象基类
纯虚函数与抽象类都是Python面向对象中重要的编程范式,用于对继承类做强制性接口实现约定. abc模块包含了一系列与抽象基类与纯虚函数相关的方法.Python中通过修改元类进行抽象基类的设定.这里P ...
- python之抽象基类
抽象基类特点 1.不能够实例化 2.在这个基础的类中设定一些抽象的方法,所有继承这个抽象基类的类必须覆盖这个抽象基类里面的方法 思考 既然python中有鸭子类型,为什么还要使用抽象基类? 一是我们在 ...
最新文章
- python syslog服务器_Python3+syslog使用及相关说明
- python控制手机自动刷新闻_Python脚本利用adb进行手机控制的方法
- [Redux/Mobx] Redux中异步action和同步action最大的区别是什么?
- win7计算机右键属性桌面进程重启,win7计算机右键属性打不开怎么办
- J2EE开发时的包命名规则
- Linux系统时间不同步问题
- 【Python】CentOs7 Python3安装Openssl以及解决ssl问题
- Vue 新手引导标签
- PHP excel模板
- html黑洞效果,HTML5 Canvas炫酷宇宙黑洞引力特效
- gatk过滤_vcf文件过滤
- 对bootstrop中左右浮动设置
- linux设定u盘启动,cdlinux u盘启动,教您如何设置
- 西安电子科技大学-概率论与数理统计大作业-概率论与数理统计在日常生活和社会经济中的应用
- mysql导数据出现Incorrect string value: '\xF0\x9F\x90\x82'报错
- 入门级蓝牙遥控小车制作教程
- 拼多多商品详情页 API接口、拼多多商品SKU数据接口 API接口、拼多多关键词搜索接口 API接口 API接口、拼多多关键词采集 API接口、拼多多采集接口 API接口、拼多多详情 API接口
- vue实例中template: App,这样写是什么意思
- c语言编程模拟机械钟表行走,C语言课程设计报告-模拟时钟转动程序
- 如何在ownCloud/NextCloud/丰盘ECM等免费企业网盘集成在线Office?
热门文章
- 2014.8.20日结
- C语言中volatile关键字与汇编__volatile__
- 如何删除表中的重复记录?等等常用SQL语句的积累
- oracle表修改语句,Oracle的常用修改表及字段的语句
- mysql中连接和断开数据库_robot framework——连接和断开mysql数据库
- 使用Python检查密码安全程度
- Python泛型函数与单分发器
- Python绘制带标记和箭头的树结构
- github怎么隐藏自己的pr记录_在GitHub中向开源框架提交PR的过程
- html5飞机发射教程,Javascript学习笔记(13_5) --js事件(飞机发射子弹)