当前位置: 首页 > news >正文

用人话讲计算机:Python篇!(十五)迭代器、生成器、装饰器

一、迭代器

(1)定义

标准解释:迭代器是 Python 中实现了迭代协议的对象,即提供__iter__()和 __next__()方法,任何实现了这两个方法的对象都可以被称为迭代器。

所谓__iter__(),即返回迭代器自身

所谓__next__(),即返回容器的下一个元素。

(是不是没看懂,别急,听下面的人话怎么说)

简单来说,你听我慢慢道来

首先,我们看python中的 for 循环:

for i in 对象

其中,对象必须是可迭代的,什么叫可迭代,就比如对象是[1,2,3],i会依次变为1,2,3,那么这个对象就是可迭代的,如果这个对象是33,i只会变成33,这行代码还会报错,这个对象就是不可迭代的

然后,我们来理解下这行代码的逻辑

如果对象是[1,2,3],那么它是可以迭代的,而这个可以迭代的对象就叫做__iter__( ) 方法

所以这一点,我们可以这么理解,如果没有__iter__( )方法,那么对象就不可迭代,那么程序就会报错。

当 i 依次变为1,2,3的过程中,它能自己变,就是从1变成2,又从2变成3,这种可以自动下一个的过程就叫做__next__()方法

那么迭代器我们就可以这么去理解了:

迭代器=__iter__()方法+ __next__()方法

即,一个对象,它具有__iter__()方法和__next__()方法,那么它就是迭代器

(注意,诸如__iter__()中左右横线是英文状态下的两个“_”连在一起的) 

(2)使用

我们来看一个迭代器的例子,加深理解:

list = [1, 2, 3]# 用inter()方法获取迭代器对象
a = iter(list)# 使用迭代器遍历元素
print(next(a)) # 输出 1
print(next(a)) # 输出 2
print(next(a)) # 输出 3# 若再写一行print(next(a))
# 则下一次调用将会抛出 StopIteration 异常,因为列表中没有更多的元素了

解释:

我们首先定义一个列表,

然后用 iter()方法获取了可迭代对象

最后再用 next()方法进行了输出

注意:有人可能发现我们之前一直说的都是__iter__(),而这里写的却是 iter()

原因在于,这里代码中的 iter() 是一个函数,它用于调用该对象的 __iter__() 方法,进而返回一个迭代器。

那么,什么时候写 iter( )什么时候写__iter__( ) 呢?

  •  何时写 iter( ):

当你已有一个可迭代对象,并希望得到它的迭代器时,你可以直接使用 iter() 函数。

例如,你有一个列表,想获取它的迭代器。

  • 何时写__iter__( ) :

你创建了一个类,并希望它可以被 for 循环遍历,或者可以被 next() 函数逐个获取元素

(这个新概念“类”,不懂可以先跳过,后面的章节会详细解释,什么叫“类”)


说起使用,这里还有个重要知识点:获取迭代器的值

在上面的例子中,我们可以看到获取迭代器的值,用的是 next(迭代器对象)

其实,我们还可以用  迭代器对象.__next__()  来获取,如:

补充::除此之外,还可以用一个报错的方法来输出

为啥我说报错呢,因为for循环时内部会报错,但是我们看不到而已。

(3)作用

我们使用时可以发现,迭代器输出时是一个一个往外蹦的,我们不用next方法,它就不会输出。

所以这里的一个重要作用,便是它只有在需要时才计算和返回下一个数据。

这意味着它们不会一次性计算出所有结果,而是每次调用时都产生下一个值,从而避免了不必要的计算和内存占用。

二、生成器

(1)定义

生成器,就是一个特殊的迭代器。

特殊在哪呢?

就在于,它多了个带 yield 关键字的函数

什么是yield关键字?

你可以把它理解为函数里的return

它长什么样?它长下面这样:

其中,gen就是一个生成器。

前面那个my_generator()函数,后面不是带了三个yield吗,所以给gen后,gen就变成生成器了。

(2)yield关键字

我们来详细解释下,这个yield关键字:

首先,我们要知道,使用 yield 关键字的函数会变成一个生成器,从此,它就不是普通的函数了。(yield可以有多个)

与return不同的是: 

  • 每次调用yield时,函数会暂停,并返回一个值。

即计算机执行完第一个print(next(gen))时,函数会将当前第一个值 1 返回,然后自身暂停到yield1和yield2之间。

执行第二个print(next(gen))时,函数就从新起步,然后返回当前第一个值 2 (因为它之前不是暂停到yield1和yield2之间了吗,所以此时2是第一个值),然后再次暂停到了yield2和yield3之间

依次类推,是谓函数会暂停,并返回一个值。

所以,到此,生成器的作用也就体现出来了,即:它可以暂停函数的执行,并在 需要时恢 复执行,不会一次性生成所有的数据,而是什么时候需要,什么时候 生成,从而节省内存。 

(3)生成器的执行

说白了,就是输出值:

我们之前说了,生成器是特殊的迭代器,所以迭代器获取值的方法,生成器同样适用,即:

  • next(生成器对象)
  • 生成器对象.__next__()
  • 用for遍历


我们来看一个复杂点的例子:

def fun1(L:list):    #L:list 表明 L参数预期得到一个列表类型sum = 0for i in L:sum += iyield suml=[1,4,3]
print(list(fun1(l)))    #list()将结果转换为易看懂的列表#输出[1, 5, 8]

当l列表中第一个元素 1 到函数fun1中时,sum=1 ,返回1,然后暂停

当l列表中第二个元素 4 到函数fun1中时,sum=1+4,返回5,然后暂停

当l列表中第三个元素 3 到函数fun1中时,sum=5+3,返回8

而,如果把上面的yield换成return的话,最终只会输出一个1,然后之间结束了(记得删掉list(),因为yield返回的是迭代对象,所以需要转化,而return的话则不需要)



(4)传值

前文我们说了不少获取值的方法,其实这里还有个传入值的方法,那就是send()函数

格式:生成器对象.send(value)

其中value这个参数可有,也可无。但作用很不同。

  • 当无参数时,我们将value写作None,即 生成器对象.send(None)

此时,它和 next() 函数的功能完全相同,如图:

  • 当有参数时,它会将暂停的程序继续执行,而 value 值会赋值给之前暂停 yield 。
def a():b = yield "hello"    #此时b是第一个yield的接受者c = yield b          #此时c是第二个yield的接受者yield cprint(b)             #输出b的值print(c)             #输出c的值yield "输出完毕"d = a()print(d.send(None))
print(d.send(1))    #将值1输送进去
print(d.send(2))    #将值2输送进去print("输出b、c的值:")
print(d.send(None))

输出:

hello
1
2
输出b、c的值:
1
2
输出完毕

解释:

执行print(d.send(None))时,相当于next方法,即将yield返回,所以首先输出hello。(注意此时b还没有被赋值,便已经暂停了。)

执行print(d.send(1))时,值1被赋值给被暂停的yield,所以成了b=1

然后继续执行代码c = yield b

此时遇到yield,所以输出b的值1,然后暂停。

执行print(d.send(2)),将刚才暂停的yield值赋值为2,所以成了c=2,然后继续执行到第三个yield语句,输出c的值。

最后,我们又用send检验了一下b和c的值,发现确实是这样。

(5)停止运行

如果说,我们想终止该生成器,让其后续将无法再调用 next() 函数 或者 __next__() 方法启动执行,否则抛出 StopIteration 异常

我们可以使用close()函数

如图

三、装饰器

(1)定义

标准解释:在Python中,装饰器(decorators)是一种高级功能,它允许你在不修改 原有函数或方法定义的情况下,给函数或方法添加新的功能。装饰器本质上 是一个函数,它接收一个函数作为参数,并返回一个新的函数或修改原来的 函数。

用人话来说,比如我们有一个a函数,a函数中有 b功能代码、c功能代码、d功能代码等等。

我们不想直接去修改b功能代码,因为c功能等可能跟b有关系,要修改b的话,可能整个a函数的各板块都要大改。

所以我们可以用装饰器说明一下,即,在别处写好一个n功能代码,然后使用装饰器,让n功能代码平替了b功能代码,这样就不用大改了。

(2)格式

格式: @须装饰的函数名

此时,我们称那个被装饰的函数名为装饰器

除此之外,装饰器函数一般需要函数闭包形式实现。

言内之意,就是装饰器必须是函数嵌套那样的。

(说一般,是因为还可以使用类来实现装饰器,后续文章再详细介绍)

(3)用法

比如,我们有n、c、d功能代码,我们想计算这些代码的运行时间

如果没用装饰器,我们可能会写:

import time
def a1(m):time1=time.time()b功能代码time2=time.time()time0=time2-time1   return time0
def a2(m):time1=time.time()c功能代码time2=time.time()time0=time2-time1   return time0
def a3(m):time1=time.time()d功能代码time2=time.time()time0=time2-time1   return time0
print (a1(True))
print (a2(True))
print (a3(True))

如果用上装饰器,就会简单很多,

import time
def a(m):def n():    #函数嵌套,即闭包time1=time.time()    #起始那会的时间m()time2=time.time()    #结束那会的时间time0=time2-time1    #计算时间差return time0return n@a    #启用装饰器,会将b函数平替m()
def b(x):代码
print (a(True))    #输出平替后的运行b函数的时间@a     
def c(x):代码
print (a(True))@a    
def d(x):代码
print (a(True))

相关文章:

用人话讲计算机:Python篇!(十五)迭代器、生成器、装饰器

一、迭代器 (1)定义 标准解释:迭代器是 Python 中实现了迭代协议的对象,即提供__iter__()和 __next__()方法,任何实现了这两个方法的对象都可以被称为迭代器。 所谓__iter__(),即返回迭代器自身 所谓__…...

5G -- 5G网络架构

5G组网场景 从4G到5G的网络演进: 1、UE -> 4G基站 -> 4G核心网 * 部署初中期,利用存量网络,引入5G基站,4G与5G基站并存 2、UE -> (4G基站、5G基站) -> 4G核心网 * 部署中后期,引入5G核心网&am…...

VR线上展厅的色彩管理如何影响用户情绪?

VR线上展厅的色彩管理对用户情绪的影响是多方面的,以下是专业从事VR线上展厅制作的圆桌3D云展厅平台为大家介绍的一些关键点: 情感共鸣:色彩能够激发特定的情感反应。例如,暖色调(如红色、橙色)通常与活力和…...

Vue3:uv-upload图片上传

效果图&#xff1a; 参考文档&#xff1a; Upload 上传 | 我的资料管理-uv-ui 是全面兼容vue32、nvue、app、h5、小程序等多端的uni-app生态框架 (uvui.cn) 代码&#xff1a; <view class"greenBtn_zw2" click"handleAddGroup">添加班级群</vie…...

大数据机器学习算法和计算机视觉应用07:机器学习

Machine Learning Goal of Machine LearningLinear ClassificationSolutionNumerical output example: linear regressionStochastic Gradient DescentMatrix Acceleration Goal of Machine Learning 机器学习的目标 假设现在有一组数据 x i , y i {x_i,y_i} xi​,yi​&…...

基于asp.net游乐园管理系统设计与实现

博主介绍&#xff1a;专注于Java&#xff08;springboot ssm 等开发框架&#xff09; vue .net php python(flask Django) 小程序 等诸多技术领域和毕业项目实战、企业信息化系统建设&#xff0c;从业十五余年开发设计教学工作 ☆☆☆ 精彩专栏推荐订阅☆☆☆☆☆不然下次找…...

一区牛顿-拉夫逊算法+分解+深度学习!VMD-NRBO-Transformer-GRU多变量时间序列光伏功率预测

一区牛顿-拉夫逊算法分解深度学习&#xff01;VMD-NRBO-Transformer-GRU多变量时间序列光伏功率预测 目录 一区牛顿-拉夫逊算法分解深度学习&#xff01;VMD-NRBO-Transformer-GRU多变量时间序列光伏功率预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.中科院一区…...

uniapp使用腾讯地图接口的时候提示此key每秒请求量已达到上限或者提示此key每日调用量已达到上限问题解决

要在创建的key上添加配额 点击配额之后进入分配页面&#xff0c;分配完之后刷新uniapp就可以调用成功了。...

WPF 完美解决改变指示灯的颜色

WPF 完美解决改变指示灯的颜色 原有&#xff1a;自己再做WPF页面设计后发现直接去查找页面多个控件嵌套情况下找不到指示灯&#xff08;Button实现的&#xff0c;详细可以看这篇文章 这里&#xff09;&#xff0c;具体看看来如何实现 加粗样式思路&#xff1a;无论多级嵌套&a…...

Flutter/Dart:使用日志模块Logger Easier

Flutter笔记 Flutter/Dart&#xff1a;使用日志模块Logger Easier Logger Easier 是一个为 Dart 和 Flutter 应用程序量身定制的现代化日志管理解决方案。它提供了一个高度灵活、功能丰富的日志记录系统&#xff0c;旨在简化开发者的日志管理工作&#xff0c;同时提供一定的定制…...

阿里云云服务器初始化

如果我们的云服务器出现无法挽回的错误时&#xff0c;我们可以尝试初始化云服务器进行解决。 首先搜索阿里云&#xff08;你要先确认自己已经购买了阿里云的云服务器&#xff09;&#xff1a; 登录账号后主页向下划 进入后点击管理控制台 点击进入后可以看到正在运行&#xff0…...

Python中SKlearn的K-means使用详解

文章目录 Python中SKlearn的K-means使用详解一、引言二、K-means算法原理三、使用SKlearn进行K-means聚类的步骤1、导入必要的库2、生成数据集3、创建K-means模型并设置参数4、训练模型5、预测簇标签6、可视化结果 四、总结 Python中SKlearn的K-means使用详解 一、引言 K-mea…...

红帽RHCE认证适用哪些人学习

红帽 RHCE工程师认证有着广泛的适用人群。对于初入 IT 行业的新手来说&#xff0c;RHCE 是快速建立专业基础、提升自身竞争力的绝佳途径。它能帮助新人系统地学习 Linux 系统知识&#xff0c;从基础的安装配置到复杂的网络服务管理&#xff0c;一步一个脚印地构建起坚实的技术框…...

FFmpeg 框架简介和文件解复用

文章目录 ffmpeg框架简介libavformat库libavcodec库libavdevice库 复用&#xff08;muxers&#xff09;和解复用&#xff08;demuxers&#xff09;容器格式FLVScript Tag Data结构&#xff08;脚本类型、帧类型&#xff09;Audio Tag Data结构&#xff08;音频Tag&#xff09;V…...

《Java核心技术I》Swing中的边框

边框 BorderFactory静态方法创建边框&#xff0c;凹斜面&#xff0c;凸斜面&#xff0c;蚀刻&#xff0c;直线&#xff0c;蒙版&#xff0c;空白。 边框添加标题&#xff0c;BorderFactory.createTitledBorder 组合边框&#xff0c;BorderFactory.createCompoundBorder JCo…...

MySQL 中的常见错误与排查

在 MySQL 数据库的日常运维中&#xff0c;管理员可能会遇到各种错误。无论是查询性能问题、连接异常、数据一致性问题&#xff0c;还是磁盘空间不足等&#xff0c;及时排查并解决这些问题是保证数据库稳定运行的关键。本文将列出 MySQL 中一些常见的错误及其排查方法。 一、连接…...

SQL 查询方式比较:子查询与自连接

在 SQL 中&#xff0c;子查询和自连接是两种常见的查询方式&#xff0c;它们的功能虽然可以相同&#xff0c;但实现的方式不同。本文通过具体示例&#xff0c;深入探讨这两种查询方式&#xff0c;并配合数据展示&#xff0c;帮助大家理解它们的使用场景和差异。 数据示例 假设…...

Linux下学【MySQL】所有常用类型详解( 配实操图 通俗易懂 )

每日激励&#xff1a;“当你觉得你会幸运时&#xff0c;幸运就会眷顾你&#xff0c;所以努力吧&#xff0c;只要你把事情做好&#xff0c;并觉得你会幸运&#xff0c;你将会变得幸运且充实。” 绪论​&#xff1a; 本章继续学习MySQL的知识&#xff0c;本章主要讲到mysql中的所…...

Gin-vue-admin(1):环境配置和安装

目录 环境配置如果443网络连接问题&#xff0c;需要添加代理服务器 后端运行前端运行 环境配置 git clone https://gitcode.com/gh_mirrors/gi/gin-vue-admin.git到server文件目录下 go mod tidygo mod tidy 是 Go 语言模块系统中的一个命令&#xff0c;用于维护 go.mod 文件…...

如何在centos系统上挂载U盘

在CentOS上挂载NTFS格式的U盘,需要执行一系列步骤,包括识别U盘设备、安装必要的软件、创建挂载点,并最终挂载U盘。以下是在CentOS上挂载NTFS格式U盘的详细步骤: 一、准备工作 确认CentOS版本: 确保你的CentOS系统已经安装并正常运行。不同版本的CentOS在命令和工具方面可能…...

AtCoder 第409​场初级竞赛 A~E题解

A Conflict 【题目链接】 原题链接&#xff1a;A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串&#xff0c;只有在同时为 o 时输出 Yes 并结束程序&#xff0c;否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…...

什么是EULA和DPA

文章目录 EULA&#xff08;End User License Agreement&#xff09;DPA&#xff08;Data Protection Agreement&#xff09;一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA&#xff08;End User License Agreement&#xff09; 定义&#xff1a; EULA即…...

C++.OpenGL (10/64)基础光照(Basic Lighting)

基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...

LLM基础1_语言模型如何处理文本

基于GitHub项目&#xff1a;https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken&#xff1a;OpenAI开发的专业"分词器" torch&#xff1a;Facebook开发的强力计算引擎&#xff0c;相当于超级计算器 理解词嵌入&#xff1a;给词语画"…...

Java入门学习详细版(一)

大家好&#xff0c;Java 学习是一个系统学习的过程&#xff0c;核心原则就是“理论 实践 坚持”&#xff0c;并且需循序渐进&#xff0c;不可过于着急&#xff0c;本篇文章推出的这份详细入门学习资料将带大家从零基础开始&#xff0c;逐步掌握 Java 的核心概念和编程技能。 …...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南

&#x1f680; C extern 关键字深度解析&#xff1a;跨文件编程的终极指南 &#x1f4c5; 更新时间&#xff1a;2025年6月5日 &#x1f3f7;️ 标签&#xff1a;C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言&#x1f525;一、extern 是什么&#xff1f;&…...

10-Oracle 23 ai Vector Search 概述和参数

一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI&#xff0c;使用客户端或是内部自己搭建集成大模型的终端&#xff0c;加速与大型语言模型&#xff08;LLM&#xff09;的结合&#xff0c;同时使用检索增强生成&#xff08;Retrieval Augmented Generation &#…...

【网络安全】开源系统getshell漏洞挖掘

审计过程&#xff1a; 在入口文件admin/index.php中&#xff1a; 用户可以通过m,c,a等参数控制加载的文件和方法&#xff0c;在app/system/entrance.php中存在重点代码&#xff1a; 当M_TYPE system并且M_MODULE include时&#xff0c;会设置常量PATH_OWN_FILE为PATH_APP.M_T…...

用鸿蒙HarmonyOS5实现中国象棋小游戏的过程

下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...