python语言支持多态(Python实现多态、协议和鸭子类型的代码详解)
python语言支持多态
Python实现多态、协议和鸭子类型的代码详解多态
问起面向对象的三大特性,几乎每个人都能对答如流:封装、继承、多态。今天我们就要来说一说 python 中的多态。
所谓多态:就是指一个类实例的相同方法在不同情形有不同表现形式。多态机制使具有不同内部结构的对象可以共享相同的外部接口。这意味着,虽然针对不同对象的具体操作不同,但通过一个公共的类,它们(那些操作)可以通过相同的方式予以调用。
我在《python 中的设计模式详解之:策略模式》一文中详细描述了策略模式的实现,而策略模式就是典型的多态应用。
之前的代码我就不贴了,大家可以去原文中查看。我依然还是以商品折扣的经典举例。策略模式一文中,传统的策略模式实现方式我也是用 python 代码实现的,在 java 或 c# 等语言中,实现方式也差不多。以下是 c# 代码,我只列了个架子:
|
interface promotion { double discount(order order); } class fidelitypromo : promotion / / 第一个具体策略 { / / 为积分为 1000 或以上的顾客提供 5 % 折扣 public double discount(order order) { ... } } class bulkitempromo : promotion / / 第二个具体策略 { / / 单个商品为 20 个或以上时提供 10 % 折扣 public double discount(order order) { ... } } class largeorderpromo : promotion / / 第三个具体策略 { / / 订单中的不同商品达到 10 个或以上时提供 7 % 折扣 public double discount(order order) { ... } } |
可以看到,首先要有一个接口(promotion),然后各个策略去实现这个接口。然而,python 语言没有 interface 关键字,就是说,python 里没有像 java、c# 一样的接口。
在策略模式一文的实现中,使用了抽象基类(abstract base class,abc)来实现接口,这主要是为了写法上看起来和 java、c# 等语言更加的像,易于有这些语言基础的同学理解和对比。
抽象基类是在 python 语言诞生 15 年后,python 2.6 才引入的。这里我们不详细介绍抽象基类,因为即便现在也很少有代码使用抽象基类。对于多态,python 有更好的实现方式——鸭子类型(duck typing)。
协议和鸭子类型
所谓 鸭子类型 就是:如果一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么它就是鸭子。这个概念的名字来源于 james whitcomb riley 提出的鸭子测试。
初次看到这个描述的小伙伴一定一头雾水,为了理解鸭子类型,我们不得不提到另一个名词——协议。
在面向对象编程中,协议是非正式的接口,是一组方法,只由文档和约定定义,因此,协议不能像正式接口那样施加强制性约束。而 python 的哲学就是尽量支持基本协议。
翻译成人话,就是:python 中没有接口,在需要使用接口的地方,就用协议代替。所谓协议,其实就是一组方法,和接口中定义的方法一个意思。只不过协议是不是强制性的约定,如果你不遵守协议,那么也没关系,运行时报错就是了。
这样就好理解鸭子类型了,“如果一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子” 这就表示已经遵守了协议,“那么它就是鸭子”,意味着你可以在其他用到“鸭子”的地方,用“这只鸟”替换。这不就是多态吗?
用“鸭子类型”来实现策略模式也很简单,删掉抽象基类就可以了。(这就是为什么抽象基类很少使用的原因,因为删掉代码也一样正确啊。)有兴趣的小伙伴可以自己尝试一下代码。
python 中的协议举例
python 中有很多的协议,比如迭代器协议,任何实现了 __iter__ 和 __next__ 方法的对象都可称之为迭代器,但对象本身是什么类型不受限制,这得益于鸭子类型。
|
from collections import iterable from collections import iterator class myiterator: def __iter__( self ): pass def __next__( self ): pass print ( isinstance (myiterator(), iterable)) print ( isinstance (myiterator(), iterator)) |
输出:
true
true
结语
鸭子类型是编程语言中动态类型语言中的一种设计风格,一个对象的特征不是由父类决定,而是通过对象的方法决定的。
python 不是不支持多态,而是 python 本身就是一门多态的语言。
原文链接:https://juejin.im/post/5cce423ce51d453a4a357e42
- python使用aes加密解密(python实现AES和RSA加解密的方法)
- python矩阵怎么生成(python实现矩阵打印)
- python中jieba库怎么用(详解Python数据可视化编程 - 词云生成并保存jieba+WordCloud)
- 抖音上很火的表白程序链接(我喜欢你 抖音表白程序python版)
- python selenium用法详解(python selenium执行所有测试用例并生成报告的方法)
- python 读文件报错处理(解决python写入带有中文的字符到文件错误的问题)
- python3.7对象检测(在Python中使用Neo4j的方法)
- pythonselenium自动化使用教程(selenium python 实现基本自动化测试的示例代码)
- python发送微信消息脚本(python实现给微信指定好友定时发送消息)
- python飞机大战游戏背景(python实现飞机大战游戏)
- python3和python区别(Python2与Python3的区别实例总结)
- python字符串找一个最大字符(Python查找最长不包含重复字符的子字符串算法示例)
- 卷积神经网络python实现(Python通过TensorFlow卷积神经网络实现猫狗识别)
- python如何编写判断正负数程序(Python实现判断一个整数是否为回文数算法示例)
- python用列表实现一个定时器(python 定时器,实现每天凌晨3点执行的方法)
- python做出来的游戏按什么键运行(python pygame实现方向键控制小球)
- 吴启华与曾舜晞两代张无忌同框,戏里经典的他却没活出原著的潇洒(吴启华与曾舜晞两代张无忌同框)
- 经常发这三种 朋友圈 的人,要迅速屏蔽(经常发这三种朋友圈)
- 有种尴尬叫朋友圈忘屏蔽,大学生上演社死现场,父母亲自下场吐槽(有种尴尬叫朋友圈忘屏蔽)
- 朋友圈屏蔽你的人,可以直接看淡了(朋友圈屏蔽你的人)
- 金球奖只青睐那些会戴珠宝的女人(金球奖只青睐那些会戴珠宝的女人)
- 浙江省一个县,人口超40万,建县历史超1100年(浙江省一个县人口超40万)
热门推荐
- 最简单的wds设置(快速解决WDCP面板环境磁盘撑满问题)
- linuxdocker启动报错提示参数无效(docker 报错 Exited 1 4 minutes ago的原因分析)
- docker配置和管理(Docker 容器监控原理及 cAdvisor的安装与使用说明)
- 将Excel数据导入数据库
- flink重启机制(浅谈Flink容错机制之作业执行和守护进程)
- django框架全面讲解(Django uwsgi Nginx 的生产环境部署详解)
- win10上装ubuntu系统(Windows 10 太难用如何定制你的 Ubuntu方法详解)
- CSS命名规范
- sql字母通配符(详解SQL 通配符)
- laravel常用的辅助函数介绍(Laravel框架表单验证操作实例分析)
排行榜
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9