python抽象基类的作用_Python:多态、鸭子模型和抽象基类
1. 多态
什么是多态
-- 多态,指的是一种事务具有多种形态;
-- python是一种动态语言,默认支持多态,同一个方法 调用 不同的类对象 ,执行的 结果各不相同;
多态实现
-- 继承:不同子类 继承 同一父类;
-- 重写:子类重写 同一个方法,保证执行结果各不相同;
示例
-- 有如下代码:
>>> class Animals():
... def talk(self):
... print("Animal talk")
...
>>>
>>> class People(Animals): # 继承 Animals 类
... def talk(self):
... print('People speak language')
...
>>>
>>> class Cat(Animals): # 继承 Animals 类
... def talk(self):
... print('Cat say miaomiao')
...
>>>
>>> cat = Cat()
>>> peo = People()
>>>
>>> cat.talk() # 调用 talk 方法
Cat say miaomiao
>>> peo.talk() # 调用 talk 方法
People speak language
如上所示:
-- cat 和 peo 两个对象调用同一个 talk() 方法;
-- 最后得到两种不同的结果;
多态的优点:
-- 多态可以增加代码的灵活度;
-- 是调用方法的技巧,不会影响到类的内部设计;
-- 多态可以看做 接口函数的重用,同一种接口方法 通过 接收不同的类 对象,从而实现不同的功能;
多态使用场景:
-- 方法参数接收同一父类的不同子类对象。
2. 鸭子模型
什么是鸭子模型
-- 当看到一只鸟走起来像鸭子,游泳起来也像鸭子,叫起来也像鸭子,那么这只鸟就可以被称为鸭子;
-- 鸭子模型和多态一样,都是接受不同的类对象,并调用相同的方法(即:鸭子的 游泳 和 叫 方法);
-- 对于一个鸭子模型来说,我们并 不关心接收的类对象是否真的是鸭子类,只关心这个类是如何被使用的;
-- 注意:如果这些需要被调用的方法不存在,那么将引发一个运行时错误。
示例
-- 有如下代码:
>>> class Duck:
... def quack(self):
... print("duck quack")
...
>>>
>>> class Bird: # Bird 类与 Duck 类无继承关系
... def quack(self):
... print("bird quack")
...
>>>
>>> class Dog: # Dog类与 Duck 类无继承关系
... def quack(self):
... print("dog quack")
...
>>>
>>> def animal_quack(animal): # animal_quack 方法可以调用任何对象的 quack() 方法,不关心对象是谁
... animal.quack()
...
>>>
>>> duck = Duck()
>>> bird = Bird() # bird 实例与 duck 实例无任何关系
>>> dog = Dog() # dog 实例与 duck 实例无任何关系
>>>
>>> for animal in [duck, bird, dog]:
... animal_quack(animal)
...
duck quack
bird quack
dog quack
-- 如上所示:
-- duck、bird、dog 分别来自三个不同的类,而且类之间是 没有继承关系 的;
-- duck、bird、dog 调用 animal_quack 方法,得到三种不同的结果,符合多态的特征;
鸭子模型的优点:
-- 鸭子模型不关关心类对象是什么,不需要类之间具有继承关系;
-- 鸭子模型让代码比多态更加灵活度;
多态使用场景:
-- 鸭子模型中,接收不同的类将会产生不同的行为,而无须明确知道这个类实际上是什么,这是多态的重要应用场景;
-- 实际生产环境中,主要用于 接口开发,即用同一个函数接收不同的类对象,从而实现不同的功能,而且无需关注对象之间的继承关系;
3. 抽象基类
什么是抽象基类
-- 抽象基类,这个词可能听着比较"深奥",其实 抽象 就是 假 的意思,基类 就是 父类,抽象基类 就是 假父类;
-- 具体来说,由 abc.ABCMeta 这个元类实现的类,就是抽象基类;
示例:
-- 如下代码中的 AbstractClass 类继承自 abc.ABCMeta,AbstractClass 就是抽象基类;
class AbstractClass(metaclass=abc.ABCMeta):
pass
抽象基类的作用
-- 判断是否为某个对象的实例
>>> class MyList(object):
... def __init__(self, my_list):
... self.my_list= my_list
... def __len__(self):
... return len(self.my_list)
...
>>>
>>> class NewList(MyList): # NewList 继承自 MyList
... pass
...
>>> ml = MyList(["a", "b", "c"])
>>>
>>> from collections.abc import Sized, Iterable
>>>
>>> print(isinstance(ml, Sized))
True # 返回 True,因为这里会检查实例对象中有没有__len__方法,有即输出True
>>> nl = NewList([1, 2, 3])
>>> print(isinstance(nl, MyList))
True # 返回 True,因为 nl 实例化的类 NewList 同时也是 MyList 的子类
-- 强制要求父类被子类继承,并在子类实现某个方法,否则子类初始化时就会报错;
>>> from abc import ABCMeta,abstractmethod
>>>
>>>
>>> class Source(metaclass=ABCMeta): # 创建抽象基类 Source
... @abstractmethod # 表示装饰的方法必须被子类所实现,否则会报错
... def get(self,key):
... pass
...
>>>
>>> class Mysource(Source): # 子类 Mysource 继承自 抽象基类 Source
... def get(self,key): # 实现 get 方法,这个方法是 抽象基类 Source 强制要求实现的
... pass
...
>>>
>>> class Mysource1(Source): # 子类 Mysource1 没有实现 抽象基类 Source 强制要求实现的 get 方法
... pass
...
>>> test = Source() # test 直接实例化 Source 父类
Traceback (most recent call last): # 此处报错,因为抽象类无法实现实例化
File "", line 1, in
TypeError: Can't instantiate abstract class Source with abstract methods get
>>>
>>> test = Mysource() # 此处实例化 Mysource,未报错
>>>
>>> test = Mysource1()
Traceback (most recent call last): # 报错,继承类必须实现抽象类的方法
File "", line 1, in
TypeError: Can't instantiate abstract class Mysource1 with abstract methods get
抽象基类使用场景
-- 接口强制规定,主要是 强制子类实现某个方法,否则就提示报错;
抽象基类的有点:
-- 处理继承问题方面更加规范、系统;
-- 明确调用之间的相互关系,使得继承层次更加清晰;
抽象基类的缺点:
-- 抽象基类在 python 并非在于用来继承,主要用来理解 python继承 的定义,应该 尽量使用鸭子模型;
-- 如果一定要继承接口的话,比较 推荐多继承,抽象基类容易 设计过度;
python抽象基类的作用_Python:多态、鸭子模型和抽象基类相关推荐
- python 类和对象_Python零基础入门学习33:类与面向对象编程:类的继承
注:本文所有代码均经过Python 3.7实际运行检验,保证其严谨性. 本文字数约1300,阅读时间约为3分钟. Python面向对象编程 类的继承机制 如果一个类A继承自另一个类B,就把继承者类A称 ...
- python中装饰器的作用_Python装饰器详解,详细介绍它的应用场景
装饰器的应用场景附加功能 数据的清理或添加:函数参数类型验证 @require_ints 类似请求前拦截数据格式转换 将函数返回字典改为 JSON/YAML 类似响应后篡改为函数提供额外的数据 moc ...
- python不完全支持面向对象程序设计_Python面向对象程序设计OOP入门教程【类,实例,继承,重载等】...
本文实例讲述了Python面向对象程序设计OOP.分享给大家供大家参考,具体如下: 类是Python所提供的最有用的的工具之一.合理使用时,类可以大量减少开发的时间.类也在流行的Python工具中使用 ...
- python编程从入门到实战类的定义_Python编程:从入门到实践—类
创建类 #!/usr/bin/env python # --*-- encoding:utf-8 --*-- class Dog(): """一次模拟小狗的简单尝试&qu ...
- python函数对变量的作用_python函数对变量的作用及遵循的原则
1.全局变量和局部变量 全局变量:指在函数之外定义的变量,一般没有缩进,在程序执行的全过程有效 局部变量:指在函数内部使用的变量,仅在函数内部有效,当函数退出时变量将不存在 例如: 1 n=1 #n是 ...
- java中math类的作用_Java开发知识之Java的数字处理类Math类
Java开发知识之Java的数字处理类Math类 一丶Java.text.DecimalFormat类与NumberFormat类 首先 Java.text.DecimalFormat指的是Decim ...
- python里object是什么类型_Python中的object这个叫做基类的类,它的属性和行为都有哪些?...
声明:以下仅为个人学习Python过程中总结的比较自洽的理解,事实上Python面向对象模型可能没那么简单.经查阅,Python在以前的版本还有不继承自object的类,叫做经典类. 用dir(obj ...
- python在实际中的作用_Python面向对象中__init__的实际作用是什么?
给个知乎的连接吧,知乎的例子说的应该是: 设计模式六大原则之一:迪米特法则,一个对象应该对其他对象保持最少的了解.如果类与类之间的关系越密切,耦合度越大,当一个类发生改变时,对另一个类的影响也越大. ...
- python中格式化字符串的作用_python中字符串格式化的意义(化妆)
格式 描述 %%百分号标记 #就是输出一个% %c字符及其ASCII码 %s字符串 %d有符号整数(十进制) %u无符号整数(十进制) %o无符号整数(八进制) %x无符号整数(十六进制) %X无符号 ...
最新文章
- firefox推荐插件
- GreenDao 3.x 注解中ToOne和ToMany的个人理解
- Javascript日期格式化指定格式的字符串实现
- jQuery接收后台返回的数据
- 停止了IIS服务为什么apache还是启动不了呢?
- 安装cuda 非root_linux非root用户下安装软件,搭建生产环境
- 十一款游戏教你学会 CSS!
- 恐怖logo效果展示AE模板
- Edge浏览器安装Tampermonkey插件
- BugKu_MISC_(3)
- 自动换挡型数字频率计
- 路由器不同网段虚拟服务器设置,局域网中不同网段互访?静态路由表必须要学会设置...
- 什么蓝牙耳机最好用?公认好用性价比高的蓝牙耳机推荐
- 2021年安全员-B证最新解析及安全员-B证考试平台
- find vba 模糊_EXCEL——VBA实现模糊查找并获取查找到的单元格内容
- python分析红楼梦中人物形象_《红楼梦》中女性人物形象分析
- TTN服务器LoRaWAN网关配置流程
- 【IPD】IPDPLM
- 分享一组Rpg Marker人物行走,游戏素材图片,共20张图片
- 绝地求生玩家排名预测