75、Python之函数式编程:生成器的核心方法及更多使用场景

引言

Python中的函数式编程,依托生成器,可以实现惰性求值的特性。但是,生成器其实还可以有更多的使用场景。本文就聚焦生成器,再次聊聊生成器中的主要方法以及更多的使用场景。

本文的主要内容有:

1、生成器的核心方法

2、生成器的使用场景

生成器的核心方法

首先还是来看下生成器的定义:

7633e99edda71758dccc79f97e8c511b.jpeg

生成器类中,主要用到的有这几个方法:

1、__next__()方法,用于获取生成器的下一个元素,如果没有更多元素了,则会抛出StopIteration异常。

2、send()方法,用于像生成器对象发送一个值,从而实现双向通信的场景。

3、throw()方法,用于向生成器内部引发一个异常,生成器内部可以捕获并处理该异常。

4、close()方法,用于关闭一个生成器对象。

接下来,我们通过代码实例演示一下这几个方法的使用。

def generator():
    while True:
        try:
            msg = yield '等待接收新的消息...'
            if msg:
                print(f'收到新消息: {msg}')
                if msg.lower() == 'exit':
                    break
        except ValueError:
            yield '发生异常,通信结束'
    yield '通信结束'


gen = generator()
# __next__()
print(gen.__next__())
# send()发送一个值
print(gen.send('hello python'))
# 发送一个异常
print(gen.throw(ValueError))
# __next__()
print(gen.__next__())
print(gen.close())
# 发送exit消息可以终止
print(gen.send('exit'))
# 也可以手动调用close()
# 再次调用__next__()就会抛StopIteration异常了
gen.__next__()

执行结果:

fa3d28710cb261db35090aebbf89a94e.jpeg

简单总结一下这几个方法的使用:

1、__next__()方法,前面已经介绍过,会获取到yield表达式右侧的值,如果生成器已经被耗尽(没有更多的值了),则抛出StopIteration异常,等价于内置函数next()。

2、send()方法,用于向生成器发送一个值,并使生成器继续执行下一个yield表达式。发送的值会被赋值给一个yield表达式的左侧。与__next__()方法不同,send()方法可以在生成器与调用者之间实现双向通信。

3、throw()方法,用于向生成器内部引发一个异常,生成器可以在内部捕获这个异常,并处理它。如果生成器内部没有捕获这个异常,它将传播到调用者,并终止生成器。

4、close()方法,用于关闭一个生成器对象,之后,将不能对该生成器执行任何方法,否则均会抛出StopIteration异常。

生成器的使用场景

了解了生成器中的核心方法,接下来看一下更多的应用生成器的场景。

1、基本的协程的场景

协程是一种可以在执行过程中暂停和恢复的子程序,基于生成器自动阻塞的特性,以及send()方法可以实现的双向通信功能,可以利用生成器实现基本的协程的功能,适用于异步编程和多任务的写作。

这里暂时不进行代码的演示了,后面会在并发编程中详细展开。

2、状态机

基于生成器可以实现一个简单的状态机的功能,每次可以使用send()方法来改变生成器的状态。可以通过代码来看一个简单的状态机的模拟。

直接看代码:

def state_machine():
    state = 'PLAN'
    while True:
        if state == 'PLAN':
            state = yield 'PLAN PHASE'
        elif state == 'DO':
            state = yield 'DO PHASE'
        elif state == 'CHECK':
            state = yield 'CHECK PHASE'
        elif state == 'ACT':
            state = yield 'ACT PHASE'


# 模拟PDCA/戴明环
sm = state_machine()
print(next(sm))
print(sm.send('DO'))
print(sm.send('CHECK'))
print(sm.send('ACT'))
print(sm.send('PLAN'))

执行结果:

1deb3bf0373d303cc853605100e83088.jpeg

3、实时数据处理

生成器可以用于处理实时输入的数据,例如传感器监测数据、网络日志等,通过send()方法实现实时数据的传入及处理。

以一个实时计算平均值的示例作为演示:

def calculate_avg():
    total = 0
    count = 0
    avg = None
    while True:
        num = yield avg
        total += num
        count += 1
        avg = total / count
        print(f'已接收到{count}个数字,总和:{total},平均值:{avg}')


averager = calculate_avg()
# 启动生成器,首次返回None
print(averager.__next__())
# 模拟实时传值并计算
print(averager.send(10))
print(averager.send(15))
print(averager.send(25))

执行结果:

00ede24a3193783bd993913acb5355d0.jpeg
其实代码逻辑很简单,只要能够理解生成器的基本执行原理即可,这里重点回顾一下:

next()之后会阻塞在yield表达式,send()会从上次阻塞点开始执行,首先会把传入的值赋值给yield表达式的左侧,然后一直执行到yield表达式返回结果,并阻塞,等待下次执行。

4、消息的传递与处理

由于生成器的send()双向通信的功能,以及实现基本的协程的功能,所以,生成器可以用于实现简单的消息处理系统。

5、用户输入处理

生成器可以用来处理用户的输入,比如前面例子中,根据用户的输入指令决定是只打印输出,还是终止生成器。

以上,就是本文的全部内容了。

总结

简单总结一下,本文结合生成器的定义,简单介绍了__next__()方法、send()方法、throw()方法,以及close()方法的使用。基于send()方法可以实现生成器与调用者之间双向通信的功能,简单列举了几个生成器的使用场景。

感谢您的拨冗阅读,希望对您有所帮助。

fa4d74689ed4eac2182c6bef8d04e5c2.jpeg

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

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

相关文章

解决DockerDesktop启动redis后采用PowerShell终端操作

如图: 在启动redis容器后,会计入以下界面 : 在进入执行界面后如图: 是否会觉得界面过于单调,于是想到使用PowerShell来操作。 步骤如下: 这样就能使用PowerShell愉快地敲命令了(颜值是第一生…

SVM原理

SVM 这里由于过了很长时间 博主当时因为兴趣了解了下 博主现在把以前的知识放到博客上 作为以前的学习的一个结束 这些东西来自其他资料上 小伙伴看不懂英文的自行去翻译下吧 博主就偷个懒了 多维空间和低维空间 不一样的分法,将数据映射到高维 &…

vue源码分析(九)—— 合并配置

文章目录 前言1.vue cli 创建一个基本的vue2 项目2.将mian.js文件改成如下3. 运行结果及其疑问? 一、使用 new Vue 创建过程的 2 种场景二、margeOption的详细说明1.margeOption的方法地址2.合并策略的具体使用3.defaultStrat 默认策略方法 三:以生命周期…

基于单片机的水位检测系统仿真

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 基于STC89C52单片机,DHT11温湿度采集温湿度,滑动变阻器连接ADC0832数模转换器模拟水位传感器检测水位,通过LCD1602显示信息,然后在程序里设置好是否…

docker启动mysql未读取my.cnf配置文件问题

描述 在做mysql主从复制配置两台mysql时,从节点的my.cnf配置为: [mysqld] datadir /usr/local/mysql/slave1/data character-set-server utf8 lower-case-table-names 1 # 主从复制-从机配置# 从服务器唯一 ID server-id 2 # 启用中继日志 relay-l…

【编程底层原理】Java对象头的详细结构、锁机制及其优化技术,以及逃逸分析和JIT技术在性能优化中的作用

一、引言 在Java的多线程世界中,对象头和锁机制是确保数据一致性和程序性能的关键。本文将带你深入探索Java对象头的结构、锁机制的工作原理,以及逃逸分析和即时编译(JIT)技术如何助力性能优化。 二、Java对象头 1. 对象头的组…

6.数据库-数据库设计

6.数据库-数据库设计 文章目录 6.数据库-数据库设计一、设计数据库的步骤二、绘制E-R图三、关系模式第一范式 (1st NF)第二范式 (2nd NF)第三范式 (3nd NF)规范化和性能的关系 一、设计数据库的步骤 收集信息 与该系统有关人员进行交流、座谈,充分了解用户需求&am…

8. 防火墙

8. 防火墙 (1) 防火墙的类型和结构 防火墙的类型和结构可以根据其在网络协议栈中的过滤层次和实现方式进行分类。常见的防火墙类型包括: 包过滤防火墙:工作在网络层(OSI模型的第3层),主要检查IP包头的信息,如源地址、目的地址、端口号等。电路级网关防火墙:工作在会话层…

操作系统简介

大学的操作系统课程是计算机科学与技术专业的重要基础课程之一,旨在帮助学生理解和掌握现代操作系统的基本原理和核心技术。这门课程不仅涵盖操作系统的理论知识,还包括实践内容,帮助学生在实际应用中理解操作系统的工作机制。以下是操作系统…

CSS 布局三大样式简单学习

目录 1. css 浮动 1.1 效果1 1.2 效果2 1.3 效果3 1.4 效果4 2. css 定位 2.1 absolute 2.2 relative 2.3 fixed 3. css 盒子模型 3.1 效果1 3.2 效果2 3.3 效果3 3.4 效果4 1. css 浮动 1.1 效果1 1.2 效果2 1.3 效果3 1.4 效果4 2. css 定位 2.1 absolute 2.2 …

source insight学习笔记

目录 目的 基础配置 1、护眼的保护色 2、行号显示 基础操作 目的 记录一下使用source insight中遇到的问题。比如常见好用的基础配置,常用的基础操作等。主要是为了自己以后忘记了好找。自己写的东西总归看起来更舒服。 PS:目前是第一个版本&#…

C++--模板(template)详解—— 函数模板与类模板

目录 1.泛型编程 2.函数模板 2.1 函数模板概念 2.2 函数模板格式 2.3 函数模板的原理 2.4 函数模板的实例化 2.5 模板参数的匹配原则 3.类模板 3.1 类模板的定义格式 3.2 类模板的实例化 1.泛型编程 在C中如果让你写一个交换函数,应该怎么做呢&#xff1f…

【数据结构与算法 | 灵神题单 | 二叉搜索树篇】力扣99, 1305, 230, 897

1. 力扣99:恢复二叉搜索树 1.1 题目: 给你二叉搜索树的根节点 root ,该树中的 恰好 两个节点的值被错误地交换。请在不改变其结构的情况下,恢复这棵树 。 示例 1: 输入:root [1,3,null,null,2] 输出&…

EMT-LTR--学习任务间关系的多目标多任务优化

EMT-LTR–学习任务间关系的多目标多任务优化 title: Learning Task Relationships in Evolutionary Multitasking for Multiobjective Continuous Optimization author: Zefeng Chen, Yuren Zhou, Xiaoyu He, and Jun Zhang. journal: IEE…

240922-chromadb的基本使用

A. 背景介绍 ChromaDB 是一个较新的开源向量数据库,专为高效的嵌入存储和检索而设计。与其他向量数据库相比,ChromaDB 更加专注于轻量化、简单性和与机器学习模型的无缝集成。它的核心目标是帮助开发者轻松管理和使用高维嵌入向量,特别是与生…

【计算机网络 - 基础问题】每日 3 题(十八)

✍个人博客:Pandaconda-CSDN博客 📣专栏地址:http://t.csdnimg.cn/fYaBd 📚专栏简介:在这个专栏中,我将会分享 C 面试中常见的面试题给大家~ ❤️如果有收获的话,欢迎点赞👍收藏&…

通信工程学习:什么是NFV网络功能虚拟化

NFV:网络功能虚拟化 NFV(Network Function Virtualization),即网络功能虚拟化,是一种通过虚拟化技术实现网络功能的技术手段。它借鉴了x86服务器的架构,将传统的网络硬件设备如路由器、交换机、防火墙、负载…

华为eNSP使用详解

eNSP(Enterprise Network Simulation Platform)是华为提供的一款网络仿真平台,它允许用户在没有真实设备的情况下进行网络实验和学习网络技术。eNSP可以模拟各种网络设备,如交换机、路由器、防火墙等,并支持创建多种网…

【python】【绘制小程序】动态爱心绘制

背景介绍 参考链接:https://blog.csdn.net/Python_HUHU/article/details/139703289点的背景颜色在开始修改;文字的颜色在最后修改。文字内容可以修改。 python 代码 import tkinter as tk import random from math import sin, cos, pi, log from PIL…

VMware ESXi 8.0U3b macOS Unlocker OEM BIOS 2.7 集成网卡驱动和 NVMe 驱动 (集成驱动版)

VMware ESXi 8.0U3b macOS Unlocker & OEM BIOS 2.7 集成网卡驱动和 NVMe 驱动 (集成驱动版) 发布 ESXi 8.0U3 集成驱动版,在个人电脑上运行企业级工作负载 请访问原文链接:https://sysin.org/blog/vmware-esxi-8-u3-sysin/,查看最新版…