全网最适合入门的面向对象编程教程: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 = 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)

运行结果如下:

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 = 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()

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

image

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

_# 定义类_
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()

运行结果如下:

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

vscode docker debug python

1. 安装Vscode插件 ”Docker“”Dev Containers““Remote - ssh” 2. 进入Docker环境 点击左侧 Docker图标&#xff0c;选择Containers 对容器进行右键启动 生成新页面直接进行选择文件路径即可&#xff0c;之后得操作均在容器内进行

6.1排序——插入排序与希尔排序

本篇博客来梳理两种常见排序算法&#xff1a;插入排序与希尔排序 常见的排序算法如图 写排序算法的原则&#xff1a;先写单趟&#xff0c;再写整体 一、直接插入排序 1&#xff0e;算法思想 先假定第一个数据有序&#xff0c;把第二个数据插入&#xff1b;再假设前两个数据…

读取、写入、生成txt文本文档详解——C#学习笔记

一、4中写入文本的方式&#xff1a; //①表示清空 txt StreamWriter mytxt1 new StreamWriter("D:\\1清空.txt"); string t1 ""; mytxt1.Write(t1); mytxt1.Close(); //②表示向txt写入文本 StreamWriter mytxt2 new StreamWriter("D:…

不到200行代码,一键写出简单贪吃蛇网页游戏!附详细代码!快来看看吧!

​哈喽大家好&#xff0c;这里是大白百宝阁&#xff0c;每天分享一段小代码~ 今天要分享的是&#xff0c;不到200行代码&#xff0c;制作html版贪吃蛇&#xff0c;效果如下&#xff1a; 游戏结束后&#xff0c;还会显示&#xff1a; 代码如下&#xff1a; <!DOCTYPE html&g…

GitHub图床

GitHub图床 文章目录 GitHub图床图床介绍Github访问GitHub手动修改hostsgithub520 加速器创建账户创建仓库创建token PicGoTypora 图床介绍 图床 存放图片的地方 为什么设置图床呢 在我认识图床之前, 有一个问题 [^放在typora上面的图片, 其实是一个链接, 并且将图片存放在本地…

Java之枚举

目录 枚举 引入 定义 代码示例 常用方法 代码示例 枚举的优缺点 枚举和反射 面试题 枚举 引入 枚举是在JDK1.5以后引入的。主要用途是&#xff1a;将一组常量组织起来&#xff0c;在这之前表示一组常量通常使用定义常量的方式&#xff1a; publicstaticintfinalRED1;…

树莓派通过串口驱动SU-03T语音模块

树莓派通过串口驱动SU-03T语音模块 文章目录 树莓派通过串口驱动SU-03T语音模块一、SU-03T语音模块的配置和烧录1.1 PIN引脚配置&#xff1a;1.2 设置唤醒词&#xff1a;1.3 设置控制详情&#xff1a;1.4 下载SDK并烧录到语音模块&#xff1a; 二、测试语音模块三、树莓派通过串…

汇舸环保从北交所转战港交所:狂分红超8000万,客户依赖度越来越高

《港湾商业观察》施子夫 7月31日&#xff0c;上海汇舸环保科技集团股份有限公司&#xff08;以下简称&#xff0c;汇舸环保&#xff09;递表港交所获受理&#xff0c;联席保荐机构中信证券和中国银河证券。 8月14日&#xff0c;公司披露公告称&#xff0c;另委任法国巴黎证券…

HTML零基础教程(超详细)

一、什么是HTML HTML&#xff0c;全称超文本标记语言&#xff08;HyperText Markup Language&#xff09;&#xff0c;是一种用于创建网页的标准标记语言。它通过一系列标签来定义网页的结构、内容和格式。HTML文档是由HTML元素构成的文本文件&#xff0c;这些元素包括标题、段…

99.WEB渗透测试-信息收集-网络空间搜索引擎shodan(1)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a; 易锦网校会员专享课 上一个内容&#xff1a;98.WEB渗透测试-信息收集-Google语法&#xff08;12&#xff09; 信息收集方向-网络空间…

UEFI——获取UEFI MemoryMap

一、MemoryMap简介 首先讲一下什么是MemoryMap&#xff1f; 内存映射&#xff08;Memory Mapping&#xff09;是一种将文件内容映射到进程的虚拟地址空间的技术。在这种机制下&#xff0c;文件可以视为内存的一部分&#xff0c;从而允许程序直接对这部分内存进行读写操作&…

西门子WinCC开发笔记(一):winCC西门子组态软件介绍、安装

文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/142060535 长沙红胖子Qt&#xff08;长沙创微智科&#xff09;博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV、Op…

Mysql Innodb存储引擎原理—链接如下

Mysql Innodb存储引擎| ProcessOn免费在线作图,在线流程图,在线思维导图 ProcessOn是一个在线协作绘图平台&#xff0c;为用户提供强大、易用的作图工具&#xff01;支持在线创作流程图、思维导图、组织结构图、网络拓扑图、BPMN、UML图、UI界面原型设计、iOS界面原型设计等。同…

大数据-124 - Flink State 01篇 状态原理和原理剖析:状态类型 执行分析

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

数学建模笔记—— 模糊综合评价

数学建模笔记—— 模糊综合评价 模糊综合评价1. 模糊数学概述2. 经典集合和模糊集合的基本概念2.1 经典集合2.2 模糊集合和隶属函数1. 基本概念2.模糊集合的表示方法3. 模糊集合的分类4. 隶属函数的确定方法 3. 评价问题概述4. 一级模糊综合评价模型典型例题 5. 多层次模糊综合…

SprinBoot+Vue停车场管理系统的设计与实现

目录 1 项目介绍2 项目截图3 核心代码3.1 Controller3.2 Service3.3 Dao3.4 application.yml3.5 SpringbootApplication3.5 Vue 4 数据库表设计5 文档参考6 计算机毕设选题推荐7 源码获取 1 项目介绍 博主个人介绍&#xff1a;CSDN认证博客专家&#xff0c;CSDN平台Java领域优质…

iOS——GCD再学习

GCD 使用GCD好处&#xff0c;具体如下&#xff1a; GCD 可用于多核的并行运算&#xff1b;GCD 会自动利用更多的 CPU 内核&#xff08;比如双核、四核&#xff09;&#xff1b;GCD 会自动管理线程的生命周期&#xff08;创建线程、调度任务、销毁线程&#xff09;&#xff1b…

❤《实战纪录片 1 》原生开发小程序中遇到的问题和解决方案

《实战纪录片 1 》原生开发小程序中遇到的问题和解决方案 文章目录 《实战纪录片 1 》原生开发小程序中遇到的问题和解决方案1、问题一&#xff1a;原生开发中 request请求中返回 的数据无法 使用this传递给 data{}中怎么办&#xff1f;2、刚登录后如何将token信息保存&#xf…

智汇云舟荣膺国家级专精特新“小巨人”企业称号

近日&#xff0c;北京市经济和信息化局发布了经工业和信息化部审核的第六批专精特新“小巨人”企业名单&#xff0c;智汇云舟凭借其在视频孪生领域的卓越贡献和技术实力成功入选&#xff0c;荣膺国家级专精特新“小巨人”企业称号。 专精特新“小巨人”&#xff0c;是目前全国中…

PDF 全文多语言 AI 摘要 API 数据接口

PDF 全文多语言 AI 摘要 API 数据接口 PDF / 文本摘要 AI 生成 PDF 文档摘要 AI 处理 / 智能摘要。 1. 产品功能 支持多语言摘要生成&#xff1b;支持 formdata 格式 PDF 文件流传参&#xff1b;快速处理大文件&#xff1b;基于 AI 模型&#xff0c;持续迭代优化&#xff1b;…