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

摘要:
函数是 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 类和对象的Python实现-异常和语法错误
全网最适合入门的面向对象编程教程:23 类和对象的Python实现-抛出异常
全网最适合入门的面向对象编程教程:24 类和对象的Python实现-异常的捕获与处理
全网最适合入门的面向对象编程教程:25 类和对象的Python实现-Python判断输入数据类型
全网最适合入门的面向对象编程教程:26 类和对象的Python实现-上下文管理器和with语句
全网最适合入门的面向对象编程教程:27 类和对象的Python实现-Python中异常层级与自定义异常类的实现
全网最适合入门的面向对象编程教程:28 类和对象的Python实现-Python编程原则、哲学和规范大汇总
全网最适合入门的面向对象编程教程:29 类和对象的Python实现-断言与防御性编程和help函数的使用
全网最适合入门的面向对象编程教程:30 Python的内置数据类型-object根类
全网最适合入门的面向对象编程教程:31 Python的内置数据类型-对象Object和类型Type
全网最适合入门的面向对象编程教程:32 Python的内置数据类型-类Class和实例Instance
全网最适合入门的面向对象编程教程: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实现常见数据结构-链表、树、哈希表、图和堆
更多精彩内容可看:
给你的 Python 加加速:一文速通 Python 并行计算
一个MicroPython的开源项目集锦:awesome-micropython,包含各个方面的Micropython工具库
SenseCraft 部署模型到Grove Vision AI V2图像处理模块
文档和代码获取:
可访问如下链接进行对文档下载:
https://github.com/leezisheng/Doc

本文档主要介绍如何使用 Python 进行面向对象编程,需要读者对 Python 语法和单片机开发具有基本了解。相比其他讲解 Python 面向对象编程的博客或书籍而言,本文档更加详细、侧重于嵌入式上位机应用,以上位机和下位机的常见串口数据收发、数据处理、动态图绘制等为应用实例,同时使用 Sourcetrail 代码软件对代码进行可视化阅读便于读者理解。
相关示例代码获取链接如下:https://github.com/leezisheng/Python-OOP-Demo
正文
函数
函数是一个命名的代码块,需要 0 个或多个输入参数,运行以后会返回输出值。在 Python 中,函数不仅是对象,也是第一类对象(First-Class Object),这是 Python 函数的一大特性。函数作为对象可以赋值给一个变量、可以作为元素添加到集合对象中、可作为参数值传递给其它函数,还可以当做函数的返回值,这些特性就是第一类对象所特有的。

简单来说,就是在 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 = 0
for i in range(FileterLength-1):
_# 实现列表的移位操作_
DataList[i] = DataList[i+1]
_# 实现列表求和_
sum += DataList[i]
DataList[FileterLength-1] = value
sum += DataList[FileterLength-1]
average = sum / len(DataList)
return average
我们首先访问一下这个函数的基本属性:
print(id(AverageFilter))
print(type(AverageFilter))
print(AverageFilter)
运行结果如下:

我们可以给函数添加自定义属性并且访问自定义属性:
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)
运行结果如下:

事件驱动框架计时器
接下来我们用一个事件驱动框架计时器的示例更好的说明函数作为参数可以传递到另一个函数中的相关应用。示例代码如下:
import datetime
import time
_# 定义定时器事件类_
class TimedEvent:
def __init__(self, endtime, callback):
'''
初始化方法,存储endtime和callback
:param endtime: callback执行前需要等待的时间
:param callback: 回调函数,即到达执行时间后调用的函数
'''
self.endtime = endtime
self.callback = callback
def 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()
运行结果如下,可以看到到达各自的执行时间后,每个事件都简单地输出当前时间和一段简短的消息,告诉我们调用的是哪个回调方法。

实际上类的方法也可以用作回调函数,示例代码如下
_# 定义类_
class Repeater:
def __init__(self):
self.count = 0
def 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()
运行结果如下:

从运行结果中我们不能看出,我们可以从当前正在运行的回调函数中给计时器添加新的事件。然后创建一个计时器并添加几个事件,在不同时间之后调用。
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"))
输出如下:


全网最适合入门的面向对象编程教程:46 Python函数方法与接口-函数与事件驱动框架的更多相关文章
- [Java入门笔记] 面向对象编程基础(二):方法详解
什么是方法? 简介 在上一篇的blog中,我们知道了方法是类中的一个组成部分,是类或对象的行为特征的抽象. 无论是从语法和功能上来看,方法都有点类似与函数.但是,方法与传统的函数还是有着不同之处: 在 ...
- 最适合入门的Laravel中级教程(一)
Laravel 是一个全栈框架: 我们使用 Laravel 开发业务常见有 3 个方向: 前端页面和后端逻辑混合的应用 主要是面向对 SEO 有需求的项目: 比如说新闻资讯博客文章等: 一般在控制器中 ...
- Python入门之面向对象编程(一)面向对象概念及优点
概念 谈到面向对象,很多程序员会抛出三个词:封装.继承和多态:或者说抽象.一切都是对象之类的话,然而这会让初学者更加疑惑.下面我想通过一个小例子来说明一下 面向对象一般是和面向过程做对比的,下面是一个 ...
- JavaScript基础入门12 - 面向对象编程
目录 JavaScript 面向对象编程 前言 构造函数创建对象 instanceof constructor 返回值 原型对象 关于对象的属性查找 in hasOwnProperty() JS当中实 ...
- [Java入门笔记] 面向对象编程基础(一):类和对象
什么是面向对象编程? 我们先来看看几个概念: 面向过程程序设计 面向过程,是根据事情发展的步骤,按进行的顺序过程划分,面向过程其实是最为实际的一种思考方式,可以说面向过程是一种基础的方法,它考虑的是实 ...
- Day07:常用模块,面向对象编程(对象&类)及内置函数
今日内容:1.常用模块2.面向对象编程(*****) 介绍面向对象编程 类 对象3.内置函数------------------------------1.面向过程编程 核心“ ...
- Golang的面向对象编程【结构体、方法、继承、接口】
Golang也支持面向对象编程.但与以前学过传统的面向对象编程语言有区别.1)Golang没有类class,Go语言的结构体struct和类class有相似的特性.2)Golang中不存在继承,方法重 ...
- Python - 面向对象编程 - 什么是 Python 类、类对象、实例对象
什么是对象和类 https://www.cnblogs.com/poloyy/p/15178423.html Python 类 类定义语法 最简单的类定义看起来像这样 class ClassName: ...
- 最适合入门的Laravel中级教程(二)用户认证
之前的初级教程主要是学习简单的增删改查: 接着的中级教程的目标是在初级教程的基础上能写出更复杂更健壮的程序: 我们先来学习 laravel 的用户认证功能: 在现代网站中基本都有用户系统: 而我们每开 ...
- Python入门之面向对象编程(四)Python描述器详解
本文分为如下部分 引言——用@property批量使用的例子来引出描述器的功能 描述器的基本理论及简单实例 描述器的调用机制 描述器的细节 实例方法.静态方法和类方法的描述器原理 property装饰 ...
随机推荐
- 如何在 Vue 项目中优雅地使用图标
1. 字体图标与矢量图标 目前主要有两种图标类型:字体图标和矢量图标. 字体图标是在网页打开时,下载一整个图标库,通常可以通过特定标签例如 <i> 来使用,优点是方便地实现文字混排,缺点是 ...
- 关于Windows 10 LTSC 2019无法安装Edge的解决方案
最近新换了Windows 10 LTSC 2019系统,使用体验干净且流畅,但是在更新Edge时遇到了问题:系统内装的是9x版本的Edge浏览器,并且提示更新错误,有system level方面的问题 ...
- Microsoft宣布将在开发人员会议上专注于.NET Aspire
2024年7月15日微软宣布,其开发执行团队将在下个月的开发者大会上聚焦于使用 .NET Aspire 的云原生开发,以及结合人工智能的"现代 SQL"在 Microsoft Fa ...
- KU FPGA FLASH boot失败debug
原因 新板子回来后,测试flash 烧录正常,但是无法BOOT,此时SPI设置为X4模式,使用内部时钟,速度90M.烧录过程不报错,校验也正常. FLASH理论支持最大速度108M,90M应该还好.另 ...
- Django 安全之跨站点请求伪造(CSRF)保护
Django 安全之跨站点请求伪造(CSRF)保护 by:授客 QQ:1033553122 测试环境 Win7 Django 1.11 跨站点请求伪造(CSRF)保护 中间件配置 默认的CSRF中 ...
- Anaconda Navigator打不开
问题描述:之前安装的Anaconda Navigator,好久不用了,今天却打不开了,只有那个绿色圆环图标出现在桌面中央,点一下就没了.但jupyter notebook和Spyder可以正常使用. ...
- 【Zookeeper】Win平台伪集群搭建
下载稳定版Zookeeper https://downloads.apache.org/zookeeper/stable/ GZ包: apache-zookeeper-3.6.3-bin.tar.gz ...
- 如何租GPU:一个价格还算OK的云GPU服务器租赁公司
一个价格还算OK的云GPU服务器租赁公司. 地址: https://www.gpushare.com/
- AI未来应用的新领域:具有领域知识的专属智能拼音输入法 —— 医生专属的智能输入法
本人上个月去辽宁中医看了些小毛病,在和医生交流的时候随便小聊一下,其中一个主要的话题就是"医生是否需要练习五笔".众所周知,医生的主要工作是看病,而需要使用输入法打字写病历只是看病 ...
- AQS源码深度解析之cancelAcquire方法解读
1.背景 2.源码解读 调用该方法的地方 方法源码解读 /** * 取消获取资源(异常处理时都需要用到) * 方法主要功能: * 1.处理当前取消节点的状态: * 2.将当前取消节点的前置非取消节点和 ...