python 多态 协议 鸭子类型详解


Posted in Python onNovember 27, 2021

接口(python 中的协议)的多种不同的实现方式即为多态。多态的作用,就是为了类在继承和派生的时候,保证使用“家谱”中任一类的实例的某一属性时的正确调用。

from abc import ABCMeta, abstractmethod
# 鸭子类
class Dock(metaclass=ABCMeta):
    @abstractmethod
    def Swimming(self):  # 游泳方法协议(接口)
        pass
    @abstractmethod  # 走路协议(接口)
    def Walk(self):
        pass
    @classmethod
    def __subclasshook__(cls, C):
        # 判断是否另一个比较类是否实现了 Swimming Walk 协议, 如果实现了鸭子类的这两个协议,
        # 那么比较类的类型就是一个鸭子类型
        # 当代码执行中如果执行到对象和这个类进行 isinstance 类型判断时会走到这个函数进行判断
        for method in ('Swimming', 'Walk'):
            for B in C.__mro__:
                if method in B.__dict__:
                    if B.__dict__[method] is None:
                        return NotImplemented
                    break
            else:
                return NotImplemented
        return True
# 狗类
class Dog(object):
    # 实现swimming 协议
    def Swimming(self):
        print("狗会狗刨")
    # 实现walk 协议
    def Walk(self):
        print("狗会走路")
    def Eat(self):
        print("狗喜欢吃骨头")
# 乌龟类
class Tortoise(object):
    # 实现swimming 协议
    def Swimming(self):
        print("乌龟会潜水")
    # 实现walk 协议
    def Walk(self):
        print("乌龟会走路")
    def Eat(self):
        print("乌龟喜欢吃鱼")

dog = Dog()
tortoise = Tortoise()
print(isinstance(dog, Dock))         # True
print(isinstance(tortoise, Dock))	 # True

可以看到,在上面的代码中,只要实现了 Dock 类中的 swimming 和 Walk 方法,那么这个类就可以被叫做 Dock 类

应用场景 如: for 循环, 在python 中 for 循环只能用于可迭代对象, 那么, 我自己定义的类实现了 __iter__协议(接口),这个实例类就是一个可迭代对象,可以被for 循环使用

python 中定义协议类协议使用 @abstractmethod 装饰器,@abstractmethod 装饰过的类是不能进行初始化的,相对于c++中的纯虚函数类
这个类只能当做协议(接口)类

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注三水点靠木的更多内容!

Python 相关文章推荐
Python 匹配任意字符(包括换行符)的正则表达式写法
Oct 29 Python
python获取从命令行输入数字的方法
Apr 29 Python
详解python中executemany和序列的使用方法
Aug 12 Python
Python解决抛小球问题 求小球下落经历的距离之和示例
Feb 01 Python
python实现淘宝秒杀聚划算抢购自动提醒源码
Jun 23 Python
对python 数据处理中的LabelEncoder 和 OneHotEncoder详解
Jul 11 Python
Python实现计算字符串中出现次数最多的字符示例
Jan 21 Python
Django使用uwsgi部署时的配置以及django日志文件的处理方法
Aug 30 Python
python处理excel绘制雷达图
Oct 18 Python
浅谈pytorch中torch.max和F.softmax函数的维度解释
Jun 28 Python
numpy中生成随机数的几种常用函数(小结)
Aug 18 Python
Python调用ffmpeg开源视频处理库,批量处理视频
Nov 16 Python
Python机器学习实战之k-近邻算法的实现
Python Django项目和应用的创建详解
python playwright 自动等待和断言详解
Nov 27 #Python
Python实现制作销售数据可视化看板详解
Python 如何利用ffmpeg 处理视频素材
实操Python爬取觅知网素材图片示例
Python函数中apply、map、applymap的区别
Nov 27 #Python
You might like
基于Zookeeper的使用详解
2013/05/02 PHP
推荐5款跨平台的PHP编辑器
2014/12/25 PHP
yii2整合百度编辑器umeditor及umeditor图片上传问题的解决办法
2016/04/20 PHP
PHP面向对象之事务脚本模式(详解)
2017/06/07 PHP
jquery uaMatch源代码
2011/02/14 Javascript
js模仿jquery的写法示例代码
2013/06/16 Javascript
node.js中的path.resolve方法使用说明
2014/12/08 Javascript
jQuery调用ajax请求的常见方法汇总
2015/03/24 Javascript
PHP+jQuery实现随意拖动层并即时保存拖动位置
2015/04/30 Javascript
AngularJS中如何使用$parse或$eval在运行时对Scope变量赋值
2016/01/25 Javascript
使用React实现轮播效果组件示例代码
2016/09/05 Javascript
js中string和number类型互转换技巧(分享)
2016/11/28 Javascript
Jquery EasyUI Datagrid右键菜单实现方法
2016/12/30 Javascript
js利用for in循环获取 一个对象的所有属性以及值的实例
2017/03/30 Javascript
vue-cli + sass 的正确打开方式图文详解
2017/10/27 Javascript
jQuery阻止事件冒泡实例分析
2018/07/03 jQuery
微信小程序项目实践之主页tab选项实现
2018/07/18 Javascript
JS匿名函数内部this指向问题详析
2019/05/10 Javascript
[08:44]和酒神一起战斗 DOTA2教你做大人
2014/03/27 DOTA
[47:46]完美世界DOTA2联赛 Magma vs GXR 第三场 11.07
2020/11/10 DOTA
Python socket编程实例详解
2015/05/27 Python
Python脚本简单实现打开默认浏览器登录人人和打开QQ的方法
2016/04/12 Python
NumPy 基本切片和索引的具体使用方法
2019/04/24 Python
python openpyxl使用方法详解
2019/07/18 Python
Python视频编辑库MoviePy的使用
2020/04/01 Python
Jupyter加载文件的实现方法
2020/04/14 Python
Python使用多进程运行含有任意个参数的函数
2020/05/02 Python
Python3 webservice接口测试代码详解
2020/06/23 Python
波兰运动鞋网上商店:e-Sporting
2018/02/16 全球购物
捷克家电和家具购物网站:OKAY.cz
2020/07/23 全球购物
PHP引擎php.ini参数优化深入讲解
2021/03/24 PHP
工程业务员工作职责
2013/12/07 职场文书
中学推普周活动总结
2015/05/07 职场文书
python库sklearn常用操作
2021/08/23 Python
Python Pandas 删除列操作
2022/03/16 Python
Android开发 使用文件储存的方式保存QQ密码
2022/04/24 Java/Android