[Python学习日记-66] 多态与多态性

[Python学习日记-66] 多态与多态性

简介

多态

多态性

鸭子类型

简介

        多态与多态性都是面向对象的特征之一,它们都是面向对象编程的一个重要概念,在 Python 当中也有一些独特的见解和用法,下面我们一起来了解一下是怎么回事吧。

多态

        多态指的是一类事物有多种形态,即指的是同一种操作作用于不同的对象,可以有不同的行为和结果,例如动物有多种形态:人、狗、猪

# 多态:同一类事物的多种形态
import abcclass Animal(metaclass=abc.ABCMeta):  # 同一类事物:动物@abc.abstractmethoddef talk(self):passclass People(Animal):  # 动物的形态之一:人def talk(self):print('say hello')class Dog(Animal):  # 动物的形态之二:狗def talk(self):print('say wangwang')class Pig(Animal):  # 动物的形态之三:猪def talk(self):print('say aoao')

        再聚一个例子,以文件来说也有多种形态,例如文本文件、可执行文件

import abcclass File(metaclass=abc.ABCMeta):    # 同一类事物:文件@abc.abstractmethoddef click(self):passclass Text(File):    # 文件的形态之一:文本文件def click(self):print("open file")class ExeFile(File):    # 文件的形态之二:可执行文件def click(self):print("execute file")

        这就是类之间的多态了,多态在现实当中的例子多到数不胜数,但是了解完之后感觉好像没多大作用,其实真正的重头戏是在后面的多态性当中提现。

多态性

一、什么是多态动态绑定

        多态性是指在不考虑实例类型的情况下使用实例,多态性分为静态多态性和动态多态性:

  • 静态多态性:我们常用的运算符就是静态多态性,例如任何类型(int 和 list 等)都可以用运算符(+、-、*、/、% 等)进行运算
  • 动态多态性:如下代码所示
peo1 = People()
dog1 = Dog()
pig1 = Pig()# peo1、dog1、pig1 都是动物,只要是动物肯定有 talk 方法
peo1.talk()
dog1.talk()
pig1.talk()

代码输出如下:

        更进一步,我们可以以定义一个统一的接口来使用

def func(animal):animal.talk()func(peo1)
func(dog1)
func(dog1)

代码输出如下:

二、为什么要用多态性

        其实大家从上面多态性的例子可以看出,我们并没有增加什么新的知识,也就是说 Python 本身就是支持多态性的,但这么做的好处是什么呢?它的好处如下:

1、增加了程序的灵活性

        以不变应万变,无论对象千变万化,使用者都是用同一种形式去调用,例如 func(animal)

2、增加了程序的可扩展性

        通过继承 animal 类创建了一个新的类,使用者无需更改自己的代码,还是用 func(animal) 去调用,如下

# 在上面的动物的代码的基础上增加一个 Cat 类
class Cat(Animal):  # 动物的形态之四:猫def talk(self):print('say miaomiao')# 只需要实例化一个新的对象,之后调用 talk 方法的方式和未扩展之前的形式是一摸一样的,而且以前的代码都不需要改变def func(animal):    # 对于使用者来说,自己的代码根本无需改动animal.talk()cat1 = Cat()    # 实例出一只猫
func(cat1)    # 甚至连调用方式也无需改变,就能调用猫的 talk 功能

代码输出如下:

         这样我们新增了一个猫的形态,由 Cat 类产生的实例 cat1,使用者可以在完全不需要修改自己代码的情况下,使用和人、狗、猪一样的方式去调用 talk 方法。

鸭子类型

        Python 是一个崇尚鸭子类型的语言,即“如果看起来像、叫声像而且走起路来像鸭子,那么它就是鸭子”的意思。

        Python 程序员通常根据这种行为来编写程序。例如,如果想编写现有类的自定义版本,可以继承该类也可以创建一个外观和行为很像,但与它无任何关系的全新类,后者通常用于保存程序组件的松耦合度。下面我们举两个例子来看看

例1:利用标准库中定义的各种“与文件类似”的类,尽管这些类的工作方式像文件,但他们没有继承内置文件类的方法

# 二者都像鸭子,二看看起采都像文件,因面就可以当文件一样去用
class Disk:def read(self):print('disk read')def write(self):print('disk write')class Text:def read(self):print('text read')def write(self):print('text write')# 执行文件操作
# f = open(...)  # 定义了一个文件对象
# f.read()
# f.write()disk = Disk()
text = Text()disk.read()
disk.write()text.read()
text.write()

代码输出如下:

        上面的 Disk 和 Text 与我们之前学的文件操作的功能是一样的,都是有 read 和 write,,看起来和文件操作一模一样,但是实际上并不是都读文件(其中 Disk 就是读取硬盘的模拟操作),这就是鸭子类型。

例2:序列类型有多种形态:字符串(str)、列表(list)、元组(tuple),他们有相同的方法,但他们直接没有直接的继承关系

# 序列类型: 列表(list),元组(tuple),字符串(str)
l = list([1,2,3])
t = tuple(('a','b','c'))
s = str('hello')print(l.__len__())
print(t.__len__())
print(s.__len__())

代码输出如下:

        上面三种类型的变量虽然都不同的序列,但是可以使用一样的函数,这是鸭子类型的一种体现,即字符串(str)、列表(list)、元组(tuple)这是三个独立的类,这三个类都有相同功能和名称函数。但其实上面的代码当中都只是普通的类的实例化成对象,而 Python 把它们都做得像序列一样,所以他们都被统称为序列类型,我们从源码看看这三个类到底有没有继承同一个叫做序列类型的父类,源码如下:

注意:这里的继承 object 类是由于 list、tuple、str 都是新式类,所以都会继承的,而在 Python3 中所有的类都是新式类

        当然它们也有多态性的特性,可以使用统一的接口进行调用,如下

def len(obj):return obj.__len__()print(len(l))
print(len(t))
print(len(s))

代码输出如下:

        其实这一种统一接口在 Python 中已经内置好了,我们平时使用时就无需自己写函数了,直接使用 len() 就可以了。

        Python 之所以可以在不同的类之间使用相同的函数,而之间又没有继承关系,是因为 Python 崇尚鸭子类型,类与类之间只要做得像就行了,这体现了 Python 的多态性,这是一种理论层面的东西。鸭子类型总的来说就是看着像鸭子就行了,并不需要真正的使用父类来约束子类。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/60631.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux基础1

Linux基础1 Linux基础1学习笔记 ‍ 声明! ​​​学习视频来自B站up主 泷羽sec 有兴趣的师傅可以关注一下,如涉及侵权马上删除文章 笔记只是方便各位师傅的学习和探讨,文章所提到的网站以及内容,只做学习交流,其他…

GESP4级考试语法知识(贪心算法(二))

排队接水2代码&#xff1a; #include<iostream> #include<cstdio> #include<algorithm> using namespace std; struct people {int num;int time; }; people s[1001]; int n,r,a[1001]; double sum,ave; bool cmp(people x,people y) {return x.time<y.t…

MySQL45讲 第二十讲 幻读是什么,幻读有什么问题?

文章目录 MySQL45讲 第二十讲 幻读是什么&#xff0c;幻读有什么问题&#xff1f;一、幻读的定义二、幻读带来的问题&#xff08;一&#xff09;语义问题&#xff08;二&#xff09;数据一致性问题 三、InnoDB 解决幻读的方法四、总结 MySQL45讲 第二十讲 幻读是什么&#xff0…

【再谈设计模式】建造者模式~对象构建的指挥家

一、引言 在软件开发的世界里&#xff0c;创建对象是一项基本且频繁的操作。然而&#xff0c;当对象的构造变得复杂&#xff0c;涉及众多属性和初始化步骤时&#xff0c;传统的构造函数方式往往会让代码陷入混乱的泥沼。就如同搭建一座复杂的建筑&#xff0c;若没有合理的规划和…

三、模板与配置(下)

三、模板与配置 8、WXSS模板样式-全局样式和局部样式 类型说明适用情景注意点全局样式定义在 app.wxss 中的样式&#xff0c;作用于每一个页面。当有一些通用的样式规则需要应用于整个小程序时&#xff0c;比如全局的字体大小、颜色、布局等。全局样式可能会被局部样式覆盖&a…

SQL面试题——抖音SQL面试题 主播播出时长

主播播出时长 现有如下数据,主播id、房间号、播出的批次号,每个批次号进出房间的时间戳、分区时间: 每一次直播都有一个上播和下播,每个房间里,同一个批次号会有两条数据,分别记录了上播和下播时间,求每个主播的播出时长? 通过上面的数据,可以清晰的看出,同一个批次…

大语言模型LLM综述

一、LM主要发展阶段 1.1、统计语言模型SLM 基于统计学习方法&#xff0c;基本思想是基于马尔可夫假设HMM建立词概率预测模型。如n-gram语言模型 1.2、神经语言模型NLM 基于神经网络来做词的分布式表示。如word2vec模型 1.3、 预训练语言模型PLM 预训练一个网络模型来做词表…

用 Python 从零开始创建神经网络(七):梯度下降(Gradient Descent)/导数(Derivatives)

梯度下降&#xff08;Gradient Descent&#xff09;/导数&#xff08;Derivatives&#xff09; 引言1. 参数对输出的影响2. 斜率&#xff08;The Slope&#xff09;3. 数值导数&#xff08;The Numerical Derivative&#xff09;4. 解析导数&#xff08;The Analytical Derivat…

防爆手机市场“百花齐放”,该怎么选?

在危险作业场景&#xff0c;如石化煤矿&#xff0c;通讯设备采购关系到提高生产效率‌&#xff0c;保障安全生产‌&#xff0c;‌符合法规要求‌。在应急救援通信场景&#xff0c;通讯设备采购&#xff0c;与保障救援行动的效率和准确性息息相关。而通信设备的性能参数是评估其…

似然函数解析

从贝叶斯定理引出似然函数 最大似然估计用来估计均值方差的 文心对似然函数的解释&#xff0c;注意 抛出正反的概率&#xff0c;就是固定均值方差的条件概率密度了

记录配置ubuntu18.04下运行ORBSLAM3的ros接口的过程及执行单目imu模式遇到的问题(详细说明防止忘记)

今天的工作需要自己录制的数据集来验证昨天的标定结果 用ORBSLAM3单目imu模式运行&#xff0c;mentor给的是一个rosbag格式的数据包&#xff0c;配置过程出了几个问题记录一下&#xff0c;沿配置流程写。 一.orbslam3编译安装 1.首先是安装各种依赖 这里不再赘述&#xff0…

实验5:网络设备发现、管理和维护

实验5&#xff1a;网络设备发现、管理和维护 实验目的及要求&#xff1a; 通过实验&#xff0c;掌握Cisco 路由器和交换机的IOS配置管理。自动从NTP服务器获取时间信息。能够利用TFTP服务器实现路由器和交换机配置文件的备份和恢复。同时验证CDP协议和LLDP协议的网络参数。完…

前端(2)——快速入门CSS

参考&#xff1a; 罗大富 CSS 参考手册 | 菜鸟教程 CSS 参考手册 1. CSS CSS全名是层叠样式表&#xff0c;中文名层叠样式表。用于定义网页样式和布局的样式表语言。 通过 CSS&#xff0c;你可以指定页面中各个元素的颜色、字体、大小、间距、边框、背景等样式&#xff0c;…

yolo标签自动标注(使用python和yolo方法)

yolo代码自动标注 1.引言1.初阶“自动标注”&#xff0c;给每个图像都生成一个固定的标注文件&#xff0c;进而在labglimg中对矩形框进行微调&#xff0c;减少标注的工作量2.高阶自动标注&#xff0c;利用我们训练好的&#xff08;但是没有特别精准的&#xff09;yolo文件先对每…

jmeter常用配置元件介绍总结之线程组

系列文章目录 安装jmeter jmeter常用配置元件介绍总结之线程组 1.线程组(用户)1.1线程组1.1.setUp线程组和tearDown线程组1.2.Open Model Thread Group(开放模型线程组)1.3.bzm - Arrivals Thread Group(到达线程组)1.4.jpgc - Ultimate Thread Group(终极线程组)1.5.jpgc - St…

spring gateway 动态路由

##yml配置 spring:application:name: public-gateway # cloud: # gateway: # routes: # - id: mybatis-plus-test # 路由的唯一标识 # uri: http://192.168.3.188:9898 # 目标服务的地址 # predicates: # - Path/test/** # 匹配…

NVT新能德科技入职测评SHL题库更新:数字推理+演绎推理高分答案、真题解析

新能德的入职Verify测评主要考察应聘者的逻辑推理能力、数学能力、数据分析能力以及处理信息的能力。根据搜索结果&#xff0c;测评通常包含以下几个部分&#xff1a; 1. **语言理解**&#xff1a;这部分包括阅读理解、逻辑填空和语句排序。要求应聘者在17分钟内完成30题&#…

学法减分交管12123模拟练习小程序源码前端和后端和搭建教程

交管推出个学法减分&#xff0c;每个驾驶员可以把被扣的6分&#xff0c;以看视频答题的形式学习回来&#xff0c;然后答题这个一共二十道题每道题60秒&#xff0c;有好多人不会&#xff0c;用咱们的小程序就可以模拟练习强化练习&#xff0c;还有拍照识别题目找到正确答案&…

element-plus <el-date-picker>日期选择器踩坑!!!!

我怎么一上午踩两个坑&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff08;大声bb&#xff09; 原来的vue2老项目是这样写的 <el-form-item label"时间" prop"time"><el-date-pickerv-model"addForm.time"typ…

JS的学习与使用

JS的学习与使用 一 什么是Javascript&#xff1f; Javascript是一门跨平台&#xff0c;面向对象的脚本语言&#xff0c;是用来控制网页行为的&#xff0c;它能使网页可以交互 java与Javascript是完全不同的语言&#xff0c;不论是概念还是设计&#xff0c;但是基础语法类似 E…