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使用scrapy采集数据过程中放回下载过大页面的方法
Apr 08 Python
Python中Continue语句的用法的举例详解
May 14 Python
python 网络编程详解及简单实例
Apr 25 Python
Java及python正则表达式详解
Dec 27 Python
Python中optparser库用法实例详解
Jan 26 Python
利用Pycharm断点调试Python程序的方法
Nov 29 Python
浅谈Scrapy网络爬虫框架的工作原理和数据采集
Feb 07 Python
Python实现将HTML转成PDF的方法分析
May 04 Python
详解如何从TensorFlow的mnist数据集导出手写体数字图片
Aug 05 Python
Python 继承,重写,super()调用父类方法操作示例
Sep 29 Python
python GUI库图形界面开发之PyQt5访问系统剪切板QClipboard类详细使用方法与实例
Feb 27 Python
用python实现名片管理系统
Jun 18 Python
Python机器学习实战之k-近邻算法的实现
Python Django项目和应用的创建详解
python playwright 自动等待和断言详解
Nov 27 #Python
Python实现制作销售数据可视化看板详解
Python 如何利用ffmpeg 处理视频素材
实操Python爬取觅知网素材图片示例
Python函数中apply、map、applymap的区别
Nov 27 #Python
You might like
Mysql中limit的用法方法详解与注意事项
2008/04/19 PHP
ThinkPHP3.1新特性之对页面压缩输出的支持
2014/06/19 PHP
ThinkPHP实现非标准名称数据表快速创建模型的方法
2014/11/29 PHP
PHP在同一域名下两个不同的项目做独立登录机制详解
2017/09/22 PHP
PHP学习笔记之session
2018/05/06 PHP
Laravel6.2中用于用户登录的新密码确认流程详解
2019/10/16 PHP
JavaScript中Math对象使用说明
2008/01/16 Javascript
javascript 可以拖动的DIV(二)
2009/06/26 Javascript
JavaScript 事件的一些重要说明
2009/10/25 Javascript
浅析jquery ajax异步调用方法中不能给全局变量赋值的原因及解决方法
2014/01/10 Javascript
jquery 新建的元素事件绑定问题解决方案
2014/06/12 Javascript
JavaScript将取代AppleScript?
2014/09/18 Javascript
jquery在ie7下选择器的问题导致append失效的解决方法
2016/01/10 Javascript
浅谈jQuery 中的事件冒泡和阻止默认行为
2016/05/28 Javascript
图文详解JavaScript的原型对象及原型链
2016/08/02 Javascript
json定义及jquery操作json的方法
2016/10/03 Javascript
微信小程序支付PHP代码
2018/08/23 Javascript
Javascript原型链及instanceof原理详解
2020/05/25 Javascript
JS常见错误(Error)及处理方案详解
2020/07/02 Javascript
解决vue的touchStart事件及click事件冲突问题
2020/07/21 Javascript
react-native 实现购物车滑动删除效果的示例代码
2021/01/15 Javascript
python 二维数组90度旋转的方法
2019/01/28 Python
python中如何使用分步式进程计算详解
2019/03/22 Python
Python使用线程来接收串口数据的示例
2019/07/02 Python
Python上下文管理器用法及实例解析
2019/11/11 Python
python实现串口通信的示例代码
2020/02/10 Python
python开发入门——列表生成式
2020/09/03 Python
在线服装零售商:SheIn
2016/07/22 全球购物
Goodee官方商店:迷你投影仪
2021/03/15 全球购物
大四本科生的自我评价
2013/12/30 职场文书
物理研修随笔感言
2014/02/14 职场文书
门球健将观后感
2015/06/16 职场文书
环境卫生标语
2015/08/03 职场文书
电力培训学习心得体会
2016/01/11 职场文书
Mysql效率优化定位较低sql的两种方式
2021/05/26 MySQL
Python基于百度API识别并提取图片中文字
2021/06/27 Python