全网最适合入门的面向对象编程教程:50 Python函数方法与接口-接口和抽象基类

全网最适合入门的面向对象编程教程:50 Python 函数方法与接口-接口和抽象基类

image

摘要:

在 Python 中,接口和抽象基类(Abstract Base Classes, ABCs)都用于定义类的结构和强制子类实现特定的方法,Python 没有内建的接口机制,但可以通过抽象基类(ABC)来模拟接口的行为。

原文链接:

FreakStudio的博客

往期推荐:

可能是全网最适合入门的面向对象编程教程:Python实现-嵌入式爱好者必看!

全网最适合入门的面向对象编程教程:00 面向对象设计方法导论

全网最适合入门的面向对象编程教程:01 面向对象编程的基本概念

全网最适合入门的面向对象编程教程:02 类和对象的Python实现-使用Python创建类

全网最适合入门的面向对象编程教程:03 类和对象的Python实现-为自定义类添加属性

全网最适合入门的面向对象编程教程:04 类和对象的 Python 实现-为自定义类添加方法

全网最适合入门的面向对象编程教程:05 类和对象的Python实现-PyCharm代码标签

全网最适合入门的面向对象编程教程:06 类和对象的 Python 实现-自定义类的数据封装

全网最适合入门的面向对象编程教程:07 类和对象的Python实现-类型注解

全网最适合入门的面向对象编程教程:08 类和对象的 Python 实现-@property 装饰器

全网最适合入门的面向对象编程教程:09 类和对象的Python实现-类之间的关系

全网最适合入门的面向对象编程教程:10 类和对象的Python实现-类的继承和里氏替换原则

全网最适合入门的面向对象编程教程:11 类和对象的Python实现-子类调用父类方法

全网最适合入门的面向对象编程教程:12 类和对象的 Python 实现-Python 使用 logging 模块输出程序运行日志

全网最适合入门的面向对象编程教程:13 类和对象的 Python 实现-可视化阅读代码神器 Sourcetrail 的安装使用

全网最适合入门的面向对象编程教程:14 类和对象的Python实现-类的静态方法和类方法

全网最适合入门的面向对象编程教程:15 类和对象的Python实现-__slots__魔法方法

全网最适合入门的面向对象编程教程:16 类和对象的Python实现-多态、方法重写与开闭原则

全网最适合入门的面向对象编程教程:17 类和对象的Python实现-鸭子类型与“file-like object“

全网最适合入门的面向对象编程教程:18 类和对象的Python实现-多重继承与PyQtGraph串口数据绘制曲线图

全网最适合入门的面向对象编程教程:19 类和对象的 Python 实现-使用 PyCharm 自动生成文件注释和函数注释

全网最适合入门的面向对象编程教程:20 类和对象的 Python 实现-组合关系的实现与 CSV 文件保存

全网最适合入门的面向对象编程教程:21 类和对象的 Python 实现-多文件的组织:模块 module 和包 package

全网最适合入门的面向对象编程教程:22 异常捕获-异常和语法错误

全网最适合入门的面向对象编程教程:23 异常捕获-抛出异常

全网最适合入门的面向对象编程教程:24 异常捕获现-异常的捕获与处理:try/except语句、文件读写示例、Exception引用

全网最适合入门的面向对象编程教程:25 异常捕获-Python 判断输入数据类型

全网最适合入门的面向对象编程教程:26 异常捕获-上下文管理器和with语句

全网最适合入门的面向对象编程教程:26 异常捕获-上下文管理器和with语句

全网最适合入门的面向对象编程教程:27 异常捕获-Python 中异常层级与自定义异常类的实现

全网最适合入门的面向对象编程教程:28 异常捕获-Python编程原则、哲学和规范大汇总

全网最适合入门的面向对象编程教程:29 异常捕获-断言与防御性编程和help函数的使用

全网最适合入门的面向对象编程教程:29 异常捕获-断言与防御性编程和help函数的使用

全网最适合入门的面向对象编程教程:30 Python的内置数据类型-object根类

全网最适合入门的面向对象编程教程:31 Python的内置数据类型-对象Object和类型Type

全网最适合入门的面向对象编程教程:32 Python的内置数据类型-类Class和实例Instance

全网最适合入门的面向对象编程教程:33 Python 的内置数据类型-对象 Object 和类型 Type 的关系

全网最适合入门的面向对象编程教程:33 Python 的内置数据类型-对象 Object 和类型 Type 的关系

全网最适合入门的面向对象编程教程:34 Python的内置数据类型-Python常用复合数据类型:元组和命名元组

全网最适合入门的面向对象编程教程:35 Python的内置数据类型-文档字符串和__doc__属性

全网最适合入门的面向对象编程教程:36 Python的内置数据类型-字典

全网最适合入门的面向对象编程教程:37 Python常用复合数据类型-列表和列表推导式

全网最适合入门的面向对象编程教程:38 Python常用复合数据类型-使用列表实现堆栈、队列和双端队列

全网最适合入门的面向对象编程教程:39 Python 常用复合数据类型-集合

全网最适合入门的面向对象编程教程:40 Python 常用复合数据类型-枚举和 enum 模块的使用

全网最适合入门的面向对象编程教程:41 Python常用复合数据类型-队列(FIFO、LIFO、优先级队列、双端队列和环形队列)

全网最适合入门的面向对象编程教程:42 Python常用复合数据类型-collections容器数据类型

全网最适合入门的面向对象编程教程:43 Python常用复合数据类型-扩展内置数据类型

全网最适合入门的面向对象编程教程:44 Python内置函数与魔法方法-重写内置类型的魔法方法

全网最适合入门的面向对象编程教程:45 Python实现常见数据结构-链表、树、哈希表、图和堆

全网最适合入门的面向对象编程教程:46 Python函数方法与接口-函数与事件驱动框架

全网最适合入门的面向对象编程教程:47 Python函数方法与接口-回调函数Callback

全网最适合入门的面向对象编程教程:48 Python函数方法与接口-位置参数、默认参数、可变参数和关键字参数

全网最适合入门的面向对象编程教程:49 Python函数方法与接口-函数与方法的区别和lamda匿名函数

更多精彩内容可看:

CM3调试系统简析

肝了半个月,嵌入式技术栈大汇总出炉

Avnet ZUBoard 1CG开发板上手—深度学习新选择

SenseCraft 部署模型到Grove Vision AI V2图像处理模块

比赛获奖的武林秘籍:09 一文速通计算机设计大赛,比赛人必看的获奖秘籍

比赛获奖的武林秘籍:08 一文速通光电设计大赛,电子人必看

比赛获奖的武林秘籍:07 一文速通电子设计大赛,电子人必看的获奖秘籍!

比赛获奖的武林秘籍:06 5 分钟速通比赛路演答辩,国奖选手的血泪经验!

比赛获奖的武林秘籍:05 电子计算机类比赛国奖队伍技术如何分工和学习内容

比赛获奖的武林秘籍:04 电子类比赛嵌入式开发快速必看的上手指南

比赛获奖的武林秘籍:03 好的创意选取-获得国奖的最必要前提

比赛获奖的武林秘籍:02 国奖秘籍-大学生电子计算机类竞赛快速上手的流程,小白必看

比赛获奖的武林秘籍:01 如何看待当代大学生竞赛中“卷”“祖传老项目”“找关系”的现象?

比赛获奖的武林秘籍:00 学科竞赛-工科类大学生绕不开的话题,你了解多少?

文档和代码获取:

可访问如下链接进行对文档下载:

https://github.com/leezisheng/Doc

image

本文档主要介绍如何使用 Python 进行面向对象编程,需要读者对 Python 语法和单片机开发具有基本了解。相比其他讲解 Python 面向对象编程的博客或书籍而言,本文档更加详细、侧重于嵌入式上位机应用,以上位机和下位机的常见串口数据收发、数据处理、动态图绘制等为应用实例,同时使用 Sourcetrail 代码软件对代码进行可视化阅读便于读者理解。

相关示例代码获取链接如下:https://github.com/leezisheng/Python-OOP-Demo

正文

1. 接口

1.1 接口的概念

1994 年,GoF 在其经典之作《设计模式》中,提出了一个至关重要的编程原则,即**“基于接口编程,而非面向实现编程”**。这一原则的英文原句为“Program to an interface, not an implementation”。在此,**所谓的“接口”,并非专指某一特定编程语言的接口定义,而是一种跨语言的概念。**它代表了开发者向使用者提供的一组功能列表,对这些功能的理解对于编程实践至关重要。简而言之,**接口定义了程序应完成的任务,而不涉及具体的实现细节。**这一原则对于提升代码的可扩展性、可维护性和灵活性具有深远影响。

通过定义接口,我们可以在实现具体功能的函数发生问题时(可能是用的没有授权的盗版模块,被人家发现了、起诉了;也可能是库的版本变了,某个重要的函数改名了/取消了)来减少代码的改动量,**通过接口和实现相分离的模式,封装不稳定的实现,暴露稳定的接口。**上下游系统在使用我们开发的功能时,只需要使用接口中声明的函数列表,这样当实现发生变化的时候,上游系统的代码基本上不需要做改动,以此来降低耦合性,提高扩展性。

同时,通过定义接口将系统分成多个小模块,每个模块只需实现自己所需的接口,而不需要关心其他模块的实现细节。这样在与他人协作时,我们只需要修改自己实现该接口的模块,而不需要修改其他模块。

1.2 接口的实现

常见的面向对象语言通常在类的接口和实现之间有明确的区分。例如,一些语言提供明确的 interface 关键字,用于定义类必须包含的方法,但是不需要实现。在这样的环境下,抽象类提供一个接口,以及众多方法中某几个的具体实现。任何类可以明确声明它实现自某个接口。

与 Java、Go 和 C++ 这些语言相比,Python 的接口设计方法有些不同。这些语言都提供了一个 interface 关键字来定义接口,而在 Python 中,却没有提供这个关键字。Python 在另一个方面与其他语言有明显的区别,python 并不要求实现接口的类来定义接口的所有抽象方法。

2. 使用类的继承实现接口

这里,我们首先定义一个数据处理类的接口,声明该类需要具有数据滤波、计算最大值、计算最小值和傅里叶变换的方法。同时定义了在初始化的过程中,需要接收哪些参数,如数据列表、滤波器点数(以平均值滤波为例,对多少个点计算平均值)等。

示例代码如下:

_# 使用typing模块提供的复合注解功能_
from typing import List_# 定义数据处理接口_
class DateProcessInterface(object):def __init__(self,DateList:List[int],FilterLength:int):'''初始化方法:param DateList: 数据列表:param FilterLength: 对多少个点做数据滤波'''passdef DateFilter(self)->List:'''数据滤波:return: List'''passdef DateCalMax(self)->int:'''计算数据最大值:return: int'''passdef DateCalMin(self)->int:'''计算最小值:return: int'''pass

在定义该接口的过程中,虽然没有实现具体操作,但是我们主要关心的是该接口类规定了数据处理的一般方法,也可以看作规范,就是我们首先会对数据进行滤波等预处理,然后计算一些时域特征进行分析。DateProcessInterface 实际上就是标准 python 的 class,不过因为形似接口所以可以将这个类看做一个接口。

为了使用接口,首先创建一个具体类来继承于 DateProcessInterface,也就是这个类是接口类的子类,提供了接口抽象方法的具体实现。

示例代码如下,这里我们需要引入 math 库去使用 sin 函数,引入 random 库生成随机数序列来模拟噪声,引入 matplotlib 库去绘图,matplotlib 库需要使用 conda 或者 pip 命令去安装:

import math
import matplotlib.pyplot as plt
import random_# 创建一个具体类来继承于DateProcessInterface_
class DateProcessClass(DateProcessInterface):def __init__(self,DateList:List[int],FilterLength:int):self.DateList       = DateListself.FilterLength   = FilterLengthself.TempList       = [0] * (self.FilterLength)def DateFilter(self)->List:_# 遍历DateList_for index,value in enumerate(self.DateList):_# 把每个值都当成传入的新的传感器的值_NowValue = value_# 表示列表求和的变量_sum = 0for i in range(self.FilterLength-1):_# 实现列表的移位操作_self.TempList[i] = self.TempList[i + 1]_# 实现列表求和_sum += self.TempList[i]self.TempList[self.FilterLength-1] = NowValuesum += self.TempList[self.FilterLength - 1]_# 求平均值_average = sum / self.FilterLength_# 将计算得到的平均值替换原始值_self.DateList[index] = average_# 计算完成后将TempList中元素清零_self.TempList = [0] * (self.FilterLength)return self.DateListdef DateCalMax(self)->int:max_value = max(self.DateList)return int(max_value)def DateCalMin(self)->int:min_value = min(self.DateList)return int(min_value)_# 创建l的索引列表,主要提供给plot函数作为x轴坐标_
index = [x for x in range(0,100)]
_# 生成一个正弦序列_
originalsignal = [math.sin(x)*10 for x in range(0,100)]
_# 生成随机数序列,模拟噪声_
noise = [random.uniform(0, 5) for x in range(0,100)]
_# 将两个列表中的元素相加_
signal = [x+y for x,y in zip(originalsignal,noise) ]
_# 创建DateProcessClass类,传入signal.copy()_
_# 通过创建signal的拷贝序列,从而不改变l的原始数据_
s = DateProcessClass(signal.copy(),10)
_# 进行数据滤波_
filtersignal = s.DateFilter()
_# 曲线绘图_
plt.plot(index,signal,'b')
plt.plot(index,filtersignal,'r')
_# 显示图像_
plt.show()
_# 打印信号最大值_
print("Signal Max value:",s.DateCalMax())
_# 打印信号最小值_
print("Signal Min value:",s.DateCalMin())

我们来看一下运行效果,可以看到我们对原始数据使用 5 点的滑动平均滤波的效果(蓝色是原始波形、红色是滤波后波形):

image

image

为了防止有人直接从我们的接口类中实例化对象,我们可以使用如下代码,在直接调用接口中方法时抛出 NotImplementedError 异常:

_# 定义数据处理接口_
class DateProcessInterface(object):def __init__(self,DateList:List[int],FilterLength:int):'''初始化方法:param DateList: 数据列表:param FilterLength: 对多少个点做数据滤波'''raise NotImplementedError

3. 使用抽象基类(ABC 类)实现接口

在 Python 编程中,抽象基类(Abstract Base Classes,简称 ABC)是一种非常有用的工具,用于定义接口和规范类的行为。抽象基类提供了一种机制,可以确保子类实现了特定的方法和属性。

抽象基类,也是类,需要使用 class 关键字进行定义,它与普通类不同之处有两点:

  • 抽象基类不能被实例化,只能被继承;
  • 子类必须实现抽象基类里定义的抽象方法,否则不能被实例化。

在 Python 中,可以使用 abc 模块来定义抽象基类。以上的 DateProcessInterface 使用抽象基类时,示例代码如下:

from abc import ABCMeta, abstractmethod
_# 使用抽象基类定义数据处理接口_
class DateProcessInterface(metaclass=ABCMeta):def __init__(self,DateList:List[int],FilterLength:int):'''初始化方法:param DateList: 数据列表:param FilterLength: 对多少个点做数据滤波'''pass@abstractmethoddef DateFilter(self)->List:'''抽象方法,数据滤波:return: List'''pass@abstractmethoddef DateCalMax(self)->int:'''抽象方法,计算数据最大值:return: int'''pass@abstractmethoddef DateCalMin(self)->int:'''抽象方法,计算最小值:return: int'''pass

这里,我们首先需要给接口类传递 metaclass 关键字参数,该关键字涉及到了元类编程的相关知识点,我们不予详细介绍,只需知道通过分配 ABCMeta 元类,可以赋予你的类为抽象基类。接下来使用 @abstractmethod 的装饰器实现了将方法标记为抽象,它们声明该类的任何子类必须实现这一方法。

具体来说,使用 @abstractmethod 装饰器的方法必须满足以下两个条件:

  • 方法必须是抽象方法,即只定义方法名和参数列表,但没有实现代码;
  • 方法必须在抽象类或者实现抽象类接口的子类中实现。

@abstractmethod 还能注解静态方法、类方法和属性。 你只需保证这个注解紧靠在方法定义前即可。

class A(metaclass=ABCMeta):@property@abstractmethoddef name(self):pass@name.setter@abstractmethoddef name(self, value):pass@classmethod@abstractmethoddef method1(cls):pass@staticmethod@abstractmethoddef method2():pass

抽象基类还可以用于类型检查,使用 isinstance()和 issubclass()函数。例如:

print(issubclass(DateProcessClass, DateProcessInterface))
print(isinstance(DateProcessClass, DateProcessInterface))

image

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

5.10 创建内核目录

首先是 创建内核的目录。 修改 cmake 然后是 创建 cmake , kernel 目录下的init 目录, init 目录下的start.s 文件,再init目录下 创建init.c init.h 文件。 然后是修改cmake 然后是 start.S 的编写 然后是 创建 init.c init.h 文件。 然后是 修改 img…

如何在WordPress中添加事件Schema(分步指南)

如果你正在举办一个在线活动,那么你可能正在寻找通过网络宣传的方法。此时,模式标记可以帮助你在搜索引擎结果中提高活动的可见性。 活动模式将帮助谷歌和其他搜索引擎更好地理解你的活动详情,使它们能够在活动列表、丰富摘要和谷歌知识面板…

通过markdown表格批量生成格式化的word教学单元设计表格

素材: 模板: 代码: import pandas as pd from python_docx_replace import docx_replace,docx_get_keys from docx import Document from docxcompose.composer import Composerdef parse_markdown_tables(file_path):with open(file_path,…

华为昇腾智算中心-智算中心测试方案与标准

本方案是企业内训课程《华为昇腾智算中心深度技术研修》的一部分授课课件的样例。方案内容中详细阐述了华为昇腾环境下智算中心的测试方案和标准,以确保硬件和软件系统在实际部署和运行中的高效性和稳定性。主要内容包括集群硬件清单、节点拓扑配置以及环境配置。硬…

MySQL数据库迁移与备份实录

这里写目录标题 事情起因的概述查看磁盘空间使用情况为了进一步的明确宕机原因,查看MySQL日志信息进一步排查 如何针对磁盘空间不足进行挂载区域的修改以及数据的迁移与备份分析与梳理如何修改MySQL数据卷的挂载位置停止MySQL服务备份 MySQL 配置文件迁移 MySQL 数据…

info 命令:查看命令手册

一、命令简介 在 Linux 系统中,可以使用 man​ 查看普通的帮助手册。还可以使用 info​ 命令阅读 Info 格式的文档。 ​info​ 文档的特点:大量使用超链接,通过方向键将光标移动到链接的文字,按下回车键,就可以切换到…

新发布的OpenAI o1生成式AI模型在强化学习方面迈出了重要的一步

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…

ROS第五梯:ROS+VSCode+C++单步调试

解决问题:在ROS项目中进行断点调试。 第一步:创建一个ROS项目或者打开一个现有的ROS项目。 第二步:修改c_cpp_properties.json 增加一段命令: "compileCommands": "${workspaceFolder}/build/compile_commands.json"第三…

[Python]案例驱动最佳入门:Python数据可视化在气候研究中的应用

在全球气候问题日益受到关注的今天,气温变化成为了科学家、政府、公众讨论的热门话题。然而,全球气温究竟是如何变化的?我们能通过数据洞察到哪些趋势?本文将通过真实模拟的气温数据,结合Python数据分析和可视化技术&a…

【诉讼流程-健身房-违约-私教课-诉讼书提交流程-民事诉讼-自我学习-铺平通往法律的阶梯-讲解(3)】

【诉讼流程-健身房-违约-私教课-诉讼书提交流程-民事诉讼-自我学习-铺平通往法律的阶梯-讲解(3)】 1、前言说明2、流程说明3、现场提交(线下)4、网上提交1-起诉书样例2-起诉书编写(1)原告信息:&…

如何将MySQL卸载干净(win11)

相信点进来的你肯定是遇到了这个问题,那就是在安装MySQL的时候操作错误,最后结果不是自己想要的。卸载重新安装又发现安装不了。其实最主要的原因就是没有将MySQL卸载干净,那么如何把MySQL卸载干净?下面本篇文章就来给大家一步步介…

sensitive-word 敏感词 v0.20.0 数字全部匹配,而不是部分匹配

敏感词系列 sensitive-word-admin 敏感词控台 v1.2.0 版本开源 sensitive-word-admin v1.3.0 发布 如何支持分布式部署? 01-开源敏感词工具入门使用 02-如何实现一个敏感词工具?违禁词实现思路梳理 03-敏感词之 StopWord 停止词优化与特殊符号 04-…

Matlab进行频率切片小波变换

Matlab进行频率切片小波变换(FSWT)源代码,将一维信号生成时频图。 输入信号可以是任何一维信号,心电信号、脑电信号、地震波形、电流电压数据等。 相比连续小波变换(CWT),频率切片小波变换(Frequency Slice Wavelet Transform,FSWT)是一种更具…

计算机毕业设计hadoop+spark知网文献论文推荐系统 知识图谱 知网爬虫 知网数据分析 知网大数据 知网可视化 预测系统 大数据毕业设计 机器学习

《HadoopSpark知网文献论文推荐系统》开题报告 一、研究背景及意义 随着互联网技术的迅猛发展和大数据时代的到来,学术文献的数量呈爆炸式增长,用户面临着严重的信息过载问题。如何高效地从海量文献中筛选出用户感兴趣的论文,成为当前学术界…

涛思数据库安装和卸载

安装 cd opt/taos/TDengine-server-2.4.0.5 sudo ./install.sh 启动taos​ 安装后,请使用 systemctl 命令来启动 TDengine 的服务进程 systemctl start taosd检查服务是否正常工作: systemctl status taosd 升级 3.0 版在之前版本的基础上&#x…

Parasoft助力Joby Aviation符合DO-178B标准

Joby Aviation,这家成立于2009年的美国高科技企业,以其对电动垂直起降(eVTOL)技术的深刻洞察与不懈追求,正引领着全球空中出行领域的革新。作为该领域的先驱者,Joby Aviation专注于研发并商业化运营其革命性…

蓝桥杯嵌入式客观题合集

十四届模拟赛二客观题 解析:STM32微控制器的I/O端口寄存器必须按32位字被访问 解析:微分电路能将三角波转换为方波;积分电路能将方波转换为三角波 解析:放大电路的本质是能量的控制与转换 解析:具有n个节点&#xff0c…

Ansible——Playbook基本功能???

文章目录 一、Ansible Playbook介绍1、Playbook的简单组成1)“play”2)“task”3)“playbook” 2、Playbook与ad-hoc简单对比区别联系 3、YAML文件语法:---以及多个---??使用 include 指令 1. 基本结构2. 数…

Java入门:09.Java中三大特性(封装、继承、多态)02

2 继承 需要两个类才能实现继承的效果。 比如:类A 继承 类B A类 称为 子类 , 衍生类,派生类 B类 称为 父类,基类,超类 继承的作用 子类自动的拥有父类的所有属性和方法 (父类编写,子类不需要…

IDEA开发HelloWorld程序

IDEA管理Java程序的结构 project(项目、工程)---project中可以创建多个modulemodule(模块)---module中可以创建多个packagepackage(包)---package中可以创建多个classclass(类)---c…