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 11 Python
python通过openpyxl生成Excel文件的方法
May 12 Python
基于Python如何使用AIML搭建聊天机器人
Jan 27 Python
Python实现时钟显示效果思路详解
Apr 11 Python
python使用matplotlib库生成随机漫步图
Aug 27 Python
python获取微信企业号打卡数据并生成windows计划任务
Apr 30 Python
浅谈Python编程中3个常用的数据结构和算法
Apr 30 Python
一篇文章彻底搞懂Python中可迭代(Iterable)、迭代器(Iterator)与生成器(Generator)的概念
May 13 Python
Python爬虫动态ip代理防止被封的方法
Jul 07 Python
python实现KNN分类算法
Oct 16 Python
pytorch sampler对数据进行采样的实现
Dec 31 Python
python中的yield from语法快速学习
Nov 06 Python
Python机器学习实战之k-近邻算法的实现
Python Django项目和应用的创建详解
python playwright 自动等待和断言详解
Nov 27 #Python
Python实现制作销售数据可视化看板详解
Python 如何利用ffmpeg 处理视频素材
实操Python爬取觅知网素材图片示例
Python函数中apply、map、applymap的区别
Nov 27 #Python
You might like
批量获取memcache值并按key的顺序返回的实现代码
2011/06/14 PHP
PHP实现页面静态化的超简单方法
2016/09/06 PHP
PHP架构及原理知识点详解
2019/12/22 PHP
推荐:极酷右键菜单
2006/11/29 Javascript
各种常用浏览器getBoundingClientRect的解析
2009/05/21 Javascript
Javascript中正则表达式的全局匹配模式分析
2011/04/26 Javascript
浅谈Javascript 执行顺序
2013/12/18 Javascript
javascript读取Xml文件做一个二级联动菜单示例
2014/03/17 Javascript
一个JavaScript防止表单重复提交的实例
2014/10/21 Javascript
分享20个提升网站界面体验的jQuery插件
2014/12/15 Javascript
js判断鼠标左、中、右键哪个被点击的方法
2015/01/27 Javascript
谈谈jQuery Ajax用法详解
2015/11/27 Javascript
jquery.uploadView 实现图片预览上传功能
2017/08/10 jQuery
Vue2.0父子组件传递函数的教程详解
2017/10/16 Javascript
vue里面v-bind和Props 利用props绑定动态数据的方法
2018/08/27 Javascript
详解如何使用webpack打包多页jquery项目
2019/02/01 jQuery
vue router 用户登陆功能的实例代码
2019/04/24 Javascript
vue.js 子组件无法获取父组件store值的解决方式
2019/11/08 Javascript
swiper实现异形轮播效果
2019/11/28 Javascript
Python中用memcached来减少数据库查询次数的教程
2015/04/07 Python
python中global用法实例分析
2015/04/30 Python
python Django框架实现自定义表单提交
2016/03/25 Python
Python中模块pymysql查询结果后如何获取字段列表
2017/06/05 Python
Python爬虫工程师面试问题总结
2018/03/22 Python
浅谈python str.format与制表符\t关于中文对齐的细节问题
2019/01/14 Python
基于python实现复制文件并重命名
2020/09/16 Python
Gtech官方网站:地毯清洁器、吸尘器及园艺设备
2018/05/23 全球购物
优秀实习生感言
2014/03/01 职场文书
战友聚会主持词
2014/04/02 职场文书
社区活动总结报告
2014/05/05 职场文书
世博会口号
2014/06/20 职场文书
基层党员对照检查材料
2014/08/25 职场文书
2015年度个人工作总结报告
2015/10/24 职场文书
Windows中Redis安装配置流程并实现远程访问功能
2021/06/07 Redis
MySQL 亿级数据导入导出及迁移笔记
2021/06/18 MySQL
面试被问select......for update会锁表还是锁行
2021/11/11 MySQL