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 subprocess模块学习总结
Mar 13 Python
Python实现同时兼容老版和新版Socket协议的一个简单WebSocket服务器
Jun 04 Python
深入理解Django中内置的用户认证
Oct 06 Python
python3获取当前文件的上一级目录实例
Apr 26 Python
Django Web开发中django-debug-toolbar的配置以及使用
May 06 Python
Python字典中的键映射多个值的方法(列表或者集合)
Oct 17 Python
Python计算库numpy进行方差/标准方差/样本标准方差/协方差的计算
Dec 28 Python
Python实现根据日期获取当天凌晨时间戳的方法示例
Apr 09 Python
Django Channels 实现点对点实时聊天和消息推送功能
Jul 17 Python
关于matplotlib-legend 位置属性 loc 使用说明
May 16 Python
Python基于smtplib模块发送邮件代码实例
May 29 Python
python 使用递归的方式实现语义图片分割功能
Jul 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
smarty 缓存控制前的页面静态化原理
2013/03/15 PHP
PHP代码优化的53个细节
2014/03/03 PHP
php通过淘宝API查询IP地址归属等信息
2015/12/25 PHP
Thinkphp 框架扩展之驱动扩展实例分析
2020/04/27 PHP
?牟┛途W扣了一??效果出?? target=
2007/05/27 Javascript
JavaScript入门教程(5) js Screen屏幕对象
2009/01/31 Javascript
获取URL地址中的文件名和参数的javascript代码
2009/09/02 Javascript
基于JQuery的模拟苹果桌面Dock效果(稳定版)
2012/10/15 Javascript
十个迅速提升JQuery性能让你的JQuery跑得更快
2012/12/10 Javascript
javascript中的变量作用域以及变量提升详细介绍
2013/10/24 Javascript
js使用数组判断提交数据是否存在相同数据
2013/11/27 Javascript
jquery采用oop模式class类的使用示例
2016/01/22 Javascript
浅析angularJS中的ui-router和ng-grid模块
2016/05/20 Javascript
jQuery事件对象总结
2016/10/17 Javascript
利用ES6的Promise.all实现至少请求多长时间的实例
2017/08/28 Javascript
vue-cli创建的项目,配置多页面的实现方法
2018/03/15 Javascript
JS数组实现分类统计实例代码
2018/09/30 Javascript
使用VUE实现在table中文字信息超过5个隐藏鼠标移到时弹窗显示全部
2019/09/16 Javascript
图解NodeJS实现登录注册功能
2019/09/16 NodeJs
[02:04]2014DOTA2国际邀请赛 BBC小组赛第三天总结
2014/07/12 DOTA
python使用PyGame绘制图像并保存为图片文件的方法
2015/04/24 Python
python 生成器协程运算实例
2017/09/04 Python
Python 逐行分割大txt文件的方法
2017/10/10 Python
对Python通过pypyodbc访问Access数据库的方法详解
2018/10/27 Python
pycharm通过ssh连接远程服务器教程
2020/02/12 Python
Pandas —— resample()重采样和asfreq()频度转换方式
2020/02/26 Python
Python 执行矩阵与线性代数运算
2020/08/01 Python
基于OpenCV的路面质量检测的实现
2020/11/04 Python
跑步、骑行和铁人三项的高性能眼镜和服装:ROKA
2018/07/06 全球购物
美国专业汽车音响和移动电子产品零售商:Car Toys
2019/05/13 全球购物
高中生学习的自我评价
2013/12/14 职场文书
幼儿园大班区域活动总结
2014/07/09 职场文书
学校安全工作汇报材料
2014/08/16 职场文书
一个成功的互联网创业项目,必须满足这些要求
2019/08/23 职场文书
比较node.js和Deno
2021/04/27 Javascript
嵌入式Redis服务器在Spring Boot测试中的使用教程
2021/07/21 Redis