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

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

image

摘要:

函数是 Python 中的一等公民,是一种可重用的代码块,用于封装特定的逻辑;事件驱动框架是一种编程模式,它将程序的控制流转移给外部事件,如用户输入、系统消息等,它事件驱动框架可以使用函数作为事件的处理逻辑。

原文链接:

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实现常见数据结构-链表、树、哈希表、图和堆

更多精彩内容可看:

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

正文

函数

函数是一个命名的代码块,需要 0 个或多个输入参数,运行以后会返回输出值。在 Python 中,函数不仅是对象,也是第一类对象(First-Class Object),这是 Python 函数的一大特性。函数作为对象可以赋值给一个变量、可以作为元素添加到集合对象中、可作为参数值传递给其它函数,还可以当做函数的返回值,这些特性就是第一类对象所特有的。

image

简单来说,就是在 Python 中可以把函数像普通变量一样任意地使用,。包括赋值,以及作为其它函数的参数和返回值。这样就能很容易地写出高阶函数与闭包的代码。而在其他应用面向对象设计的语言中(如 C++)实现类似操作,需要借助函数指针进行实现。

在许多情况下,我们需要将函数作为参数传递到另一个函数中。最典型的例子就是事件驱动编程模式,**所谓事件驱动编程模式不同于原先依次执行每个函数的编程模式,其基本的处理思路是预先设计一个事件循环所形成的程序,这个事件循环程序不断地检查目前要处理的信息,根据要处理的信息执行一个触发函数进行必要的处理。**其中这个外部信息可能来自一个目录夹中的文件,可能来自键盘或鼠标的动作,或者是一个时间事件。

从事件角度说,事件驱动程序的基本结构是由一个事件收集器、一个事件发送器和一个事件处理器组成。事件收集器专门负责收集所有事件,包括来自用户的(如鼠标、键盘事件等)、来自硬件的(如时钟事件等)和来自软件的(如操作系统、应用程序本身等)。事件发送器负责将收集器收集到的事件分发到目标对象中。事件处理器做具体的事件响应工作,它往往要到实现阶段才完全确定。在事件处理器中一般都需要提前传入一个注册好的回调函数,回调函数被注册之后,程序将继续执行后面的语句,而回调函数则会在对应事件产生后被异步调用。

函数身为一个对象,拥有对象模型的三个通用属性:id、类型、和值。在下面的代码中,我们创建了一个平均值滤波函数,实现三个周期的传感器采样值计算平均值,在代码中,DataList 为全局变量,它用来记录 FileterLength 个周期的采样值,AverageFilter(value)为滤波函数,它的输入为新采集到的数据,函数中,首先将 DataList[]中的数据进行移位,并将新采集到的数据保存到 DataList[]最后的元素中,同时计算 DataList[]中 10 个数据的和,最后返回 FileterLength 个数据和的平均值。示例代码如下:

_# 全局变量,记录三个周期的采样值_
FileterLength   = 3
DataList        = [0] * FileterLength
def AverageFilter(value):'''平均值滤波函数,实现三个周期的传感器采样值计算平均值:param value: 当前采样值:return: 滤波后的传感器数值'''global DataList_# 临时变量,存储列表中数据之和_sum = 0for i in range(FileterLength-1):_# 实现列表的移位操作_DataList[i] = DataList[i+1]_# 实现列表求和_sum += DataList[i]DataList[FileterLength-1] = valuesum += DataList[FileterLength-1]average = sum / len(DataList)return average

我们首先访问一下这个函数的基本属性:

print(id(AverageFilter))
print(type(AverageFilter))
print(AverageFilter)

运行结果如下:

image

我们可以给函数添加自定义属性并且访问自定义属性:

AverageFilter.description = ("The average value filter function realizes the calculation of the average value ""of the sensor sample value for three periods")
print(AverageFilter.description)

运行结果如下:

image

事件驱动框架计时器

接下来我们用一个事件驱动框架计时器的示例更好的说明函数作为参数可以传递到另一个函数中的相关应用。示例代码如下:

import datetime
import time_# 定义定时器事件类_
class TimedEvent:def __init__(self, endtime, callback):'''初始化方法,存储endtime和callback:param endtime:  callback执行前需要等待的时间:param callback: 回调函数,即到达执行时间后调用的函数'''self.endtime = endtimeself.callback = callbackdef ready(self):'''判断是否事件已经到达了该执行的适合:return:'''return self.endtime <= datetime.datetime.now()_# 定义定时器类,轮询检测实现任务调度_
class Timer:def __init__(self):'''初始化方法,定义一个events列表存储事件'''self.events = []def call_after(self, delay, callback):'''添加新的事件:param delay: 执行回调方法之前要等待的秒数:param callback: 回调方法callback函数应该接收一个参数:执行调用的计时器:return:'''end_time = (datetime.datetime.now() +datetime.timedelta(seconds=delay))self.events.append(TimedEvent(end_time, callback))def run(self):'''轮询检测,执行到达执行时间的回调函数:return:'''_# 轮询检测,执行到达执行时间的回调函数_while True:_# 使用一个生成器表达式,将将时间已到的事件过滤出来_ready_events = (e for e in self.events if e.ready())_# 按照顺序执行_for event in ready_events:event.callback(self)_# 执行完成后,移除已执行完毕的任务_self.events.remove(event)_# 在每次迭代过程中休眠 0.5 秒以防止系统死机_time.sleep(0.5)

下面,我们编写几个回调函数测试一下:

def format_time(message, *args):'''用字符串的 format 方法将当前时间添加到信息中,并说明变量参数:param message: 接收任意数量的定位参数:param args:    用于在函数中处理传递的位置参数序列:return: None'''_# 当前的时间,格式为:时-分-秒_now = datetime.datetime.now().strftime("%I:%M:%S")_# 格式化打印参数_print(message.format(*args, now=now))_# 回调函数:任务一_
def Task_One(timer):format_time("{now}: Called Task One")_# 回调函数:任务二_
def Task_Two(timer):format_time("{now}: Called Task Two")_# 回调函数:任务三_
def Task_Three(timer):format_time("{now}: Called Task Three")_# 创建定时器对象_
timer = Timer()
_# 添加回调函数_
timer.call_after(1, Task_One)
timer.call_after(2, Task_One)
timer.call_after(2, Task_Two)
timer.call_after(4, Task_Two)
timer.call_after(3, Task_Three)
timer.call_after(6, Task_Three)
_# 开始运行定时器_
format_time("{now}: Starting")
timer.run()

运行结果如下,可以看到到达各自的执行时间后,每个事件都简单地输出当前时间和一段简短的消息,告诉我们调用的是哪个回调方法。

image

实际上类的方法也可以用作回调函数,示例代码如下

_# 定义类_
class Repeater:def __init__(self):self.count = 0def repeater(self, timer):'''在函数中在创建一个定时任务:param timer: 定时器:return: None'''format_time("{now}: repeat {0}", self.count)self.count += 1_# 类的方法也可以用作回调函数_timer.call_after(5, self.repeater)_# 创建定时器对象_
timer = Timer()
repeater = Repeater()
_# 添加回调函数,类的方法_
timer.call_after(5, repeater.repeater)
_# 开始运行定时器_
format_time("{now}: Starting")
timer.run()

运行结果如下:

image

从运行结果中我们不能看出,我们可以从当前正在运行的回调函数中给计时器添加新的事件。然后创建一个计时器并添加几个事件,在不同时间之后调用。

Format 函数

在 Python 中,format()是一个内置函数,用于格式化字符串。format()函数提供了灵活的方式来将变量插入到字符串中,并控制它们的显示格式。

它的语法如下:

format(value, format_spec)

其中,参数说明如下:

  • value: 要格式化的值;format_spec: 格式化规范,用于指定值的显示方式。
  • format()函数返回一个格式化后的字符串。

它是通过 {} 和 : 来代替以前的 % 。format 函数可以接受不限个参数,位置可以不按顺序。示例代码如下:

_# 不设置指定位置,按默认顺序_
print("{} {}".format("hello", "world"))
_# 设置指定位置_
print("{0} {1}".format("hello", "world"))
_# 设置指定位置_
print("{1} {0} {1}".format("hello", "world"))

输出如下:

image

image

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

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

相关文章

ssm微信小程序校园失物招领论文源码调试讲解

第二章 开发技术与环境配置 以Java语言为开发工具&#xff0c;利用了当前先进的SSM框架&#xff0c;以MyEclipse10为系统开发工具&#xff0c;MySQL为后台数据库&#xff0c;开发的一个微信小程序校园失物招领。 2.1 Java语言简介 Java是由SUN公司推出&#xff0c;该公司于20…

若依框架使用MyBatis-Plus中的baseMapper的方法报错Invalid bound statement (not found):

Invalid bound statement (not found): com.ruoyi.system.mapper.hc.HcOrderMapper.selectList 解决方法 MybatisSqlSessionFactoryBean sessionFactory new MybatisSqlSessionFactoryBean(); 使用 MybatisSqlSessionFactoryBean 而非 SqlSessionFactoryBean 的原因 MyBatis-…

Elasticsearch数据写入过程

1. 写入请求 当一个写入请求&#xff08;如 Index、Update 或 Delete 请求&#xff09;通过REST API发送到Elasticsearch时&#xff0c;通常包含一个文档的内容&#xff0c;以及该文档的索引和ID。 2. 请求路由 协调节点&#xff1a;首先&#xff0c;请求会到达一个协调节点…

1分钟教你用AI制作美女热舞视频,收益可观,操作简单(附工具及教程资料)

美女跳舞&#xff0c;听着是不是就觉得会很哇塞&#xff1f; 不管是男的女的、老的少的都喜欢看&#xff0c;而且一般美女跳舞的账号涨粉都很快&#xff0c;势头都贼猛。 今天就给大家分享一个很热门的小副业——AI美女跳舞。 更多实操和AI绘画工具&#xff0c;可以扫描下方&…

新能源动力组中预充电路及电阻选型分析

新能源动力组中预充电路及电阻选型分析 1.概述2.预充电路与预充电阻3.预充电阻参数选择4.实例分析 1.概述 最近几年&#xff0c;新能源行业在中国得到迅猛发展。由于其高效、节能、低噪声、无污染等特点&#xff0c;它已成为国内工业发展的新趋势包括汽车和飞机。虽然应用在新…

地瓜直播间 | 基于X5平台智能双目深度算法详解

你是否曾经好奇过&#xff0c;机器是如何像人类一样通过双眼来感知三维世界的&#xff1f;双目深度感知技术&#xff0c;是一种模拟人类双眼视觉的高级技术&#xff0c;通过两个摄像头捕捉同一场景的不同视角&#xff0c;深度学习算法能够计算出物体的深度信息&#xff0c;从而…

PX4软/硬件(SITL/HITL)在环仿真

文章目录 介绍依赖PX4 Firmware&#xff1a; 软件在环(SITL)仿真Gazebo 软件无人机STIL连接简要示意SITL SLAM仿真总结示例 HITL 仿真 pxh常用命令MAVLink 指令使用这些命令时的注意事项 参考链接 介绍 为https://blog.csdn.net/weixin_41469272/article/details/117919845的补…

东南亚电商新蓝海:深度解析东南亚服务器租用的战略价值

在全球化日益加深的今天&#xff0c;东南亚以其独特的市场潜力和对数字化技术的积极拥抱&#xff0c;成为了跨境电商及互联网企业竞相角逐的热土。随着东南亚地区经济的快速增长和人口红利的持续释放&#xff0c;电商市场的繁荣景象尤为引人注目。然而&#xff0c;要在这一竞争…

【Linux系统编程】TCP实现--socket

使用套接字socket实现服务器和客户端之间的TCP通信。 流程如下&#xff1a; 实现代码&#xff1a; /* server.c */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <arpa/inet.h> #include <s…

【C++笔记】类和对象的深入理解(一)

【C笔记】类和对象的深入理解(一) &#x1f525;个人主页&#xff1a;大白的编程日记 &#x1f525;专栏&#xff1a;C笔记 文章目录 【C笔记】类和对象的深入理解(一)前言一.类的定义1.1类定义格式1.2访问限定符1.3类域 二.实例化2.1 实例化概念2.2对象大小 三.this指针四.练…

[A-09]ARMv8/ARMv9-Memory-内存空间(Address Spaces and Translation Regimes)

ver 0.2 更多精彩内容&#xff0c;请关注公众号 前言 任何人和组织的发展都需要空间&#xff0c;比如我们这个伟大的国家&#xff0c;幅员辽阔、大好河山决定了我们的发展潜力。这么大国土空间&#xff0c;不是随意无须的在发展&#xff0c;都是处于主动的规划(有形的手)或者…

【计网】计算机网络基础

当自律变成一种本能的习惯&#xff0c; 你就会享受到它的快乐。 --- 村上春树 --- 初识计算机网络 1 初识协议1.1 协议分层1.2 OSI七层模型1.3 TCP / IP协议 2 初识局域网2.1 什么是局域网2.2 MAC地址2.3 局域网通信 3 简单认识IP地址 1 初识协议 1.1 协议分层 首先&#…

基于微信小程序的人才招聘系统设计与实现

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 基于微信小程序JavaSpringBootVueMySQL的人才招聘系统设计与…

C++ 音频

一、采样频率 当前主流的采样频率为22.05KHz、44.1KHz、48KHz 22.05KHz&#xff1a;为FM广播声音品质 44.1KHz&#xff1a;为理论上最高的CD声音品质&#xff08;直播&#xff0c;录像&#xff0c;acc&#xff09; 48KHz&#xff1a;人耳可分辨的最高采样频率 &#xff08;…

AI预测福彩3D采取888=3策略+和值012路或胆码测试9月9日新模型预测第82弹

经过80多期的测试&#xff0c;当然有很多彩友也一直在观察我每天发的预测结果&#xff0c;得到了一个非常有价值的信息&#xff0c;那就是9码定位的命中率非常高&#xff0c;70多期一共只错了8次&#xff0c;这给喜欢打私房菜的朋友提供了极高价值的预测结果~当然了&#xff0c…

基于图神经网络的最大独立集问题的目标分支

文章目录 Abstract1 Introduction2 Related Work分支顶点选择图神经网络Abstract 分支归约方法结合了分支约束原则和归约规则,在处理以前无法管理的现实世界实例方面特别成功。分支策略决定下一个要在哪个顶点上进行分支。最近,最广泛使用的策略是选择最高度的顶点。 在这项…

OpenCV-轮廓特征

文章目录 一、简介1.意义2.类别 二、代码实现1.数据预处理2.计算周长3.绘制外接圆轮廓4.绘制外接矩阵 三、总结 一、简介 1.意义 在OpenCV中&#xff0c;轮廓检测后得到的轮廓不仅是一系列点的集合&#xff0c;还可以进一步分析以提取有用的特征。这些特征包括但不限于轮廓的…

读书记录:谷歌工作法 工作效率提升10倍的57个技巧

​ 前言 我在谷歌工作时留下的最深刻印象是“必须以全世界最快的速度取得成果”这一谷歌特有的强烈的使命感。 为什么日本的企业生产效率低下 过度推迟讨论 过分讨论 过度的交流 改变工作方式方法才是生存之道 在这样的时代&#xff0c;我们不应该害怕“自己的工作消失”&a…

使用rsyslog转发自定义日志到指定服务器

rsyslog简介 rsyslog 是一个高度可配置的、功能强大的系统日志守护进程&#xff0c;广泛用于 UNIX 和 Linux 系统中。它是 syslog 的一个扩展版本&#xff0c;提供了许多额外的功能和改进。能够收集、过滤、存储和转发日志数据。它的灵活性和扩展性使其成为现代 Linux 系统中日…

点餐小程序实战教程04变量定义和初始化

目录 1 什么是变量2 如何创建变量3 具体该选择什么类型4 变量的初始化5 await/async6 调试我们的程序7 运行我们的代码总结 日常碰到的最多的一句话是&#xff0c;我看到代码就发憷&#xff0c;我一点基础也没有。那低代码开发需要掌握什么样的基础&#xff0c;怎么才算是掌握了…