用人话讲计算机: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))

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

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

相关文章

小程序快速实现大模型聊天机器人

需求分析: 基于大模型,打造一个聊天机器人;使用开放API快速搭建,例如:讯飞星火;先实现UI展示,在接入API。 最终实现效果如下: 一.聊天机器人UI部分 1. 创建微信小程序&#xff0c…

【Android】unzip aar删除冲突classes再zip

# 解压JAR文件 jar xf your-library.jar # 解压AAR文件(AAR实际上是ZIP格式) unzip your-library.aar # 删除不需要的类 rm -rf path/to/com/example/unwanted/ # 对于JAR打包 jar cf your-library-modified.jar -C path/to/unzipped/ . # 对于AAR打包…

使用C语言编写UDP循环接收并打印消息的程序

使用C语言编写UDP循环接收并打印消息的程序 前提条件程序概述伪代码C语言实现编译和运行C改进之自由设定端口注意事项在本文中,我们将展示如何使用C语言编写一个简单的UDP服务器程序,该程序将循环接收来自指定端口的UDP消息,并将接收到的消息打印到控制台。我们将使用POSIX套…

你的第一个博客-第一弹

使用 Flask 开发博客 Flask 是一个轻量级的 Web 框架,适合小型应用和学习项目。我们将通过 Flask 开发一个简单的博客系统,支持用户注册、登录、发布文章等功能。 步骤: 安装 Flask 和其他必要库: 在开发博客之前,首…

Vue(二)

1.Vue生命周期 Vue生命周期就是一个Vue实例从 创建 到 销毁 的整个过程。生命周期四个阶段: 创建阶段:创建响应式数据。 挂载阶段:渲染模板。 更新阶段:修改数据,更新视图。 销毁阶段:销毁Vue实例。 …

macOS 配置 vscode 命令行启动

打开 vscode 使用 cmd shift p 组合快捷键,输入 install 点击 Install ‘code’ command in PATH Ref https://code.visualstudio.com/docs/setup/mac

python coding(二) Pandas 、PIL、cv2

Pandas 一个分析结构化数据的工具集。Pandas 以 NumPy 为基础(实现数据存储和运算),提供了专门用于数据分析的类型、方法和函数,对数据分析和数据挖掘提供了很好的支持;同时 pandas 还可以跟数据可视化工具 matplotli…

期权VIX指数构建与择时应用

芝加哥期权交易 所CBOE的波动率指数VIX 是反映 S&P 500 指数未来 30 天预测期波动率的指标,由于预期波动率多用于表征市场情绪,因此 VIX 也被称为“ 恐慌指数”。 VIX指数计算 VIX 反映了市场情绪和投资者的风险偏好, 对于欧美市场而言…

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

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

Elasticsearch:什么是提示工程 - prompt engineering?

提示工程流程定义 提示工程是一种工程技术,用于设计生成式 AI 工具(generative AI tools)的输入,以调整大型语言模型并优化输出。 提示(prompts)被称为输入,而由生成性 AI 工具生成的答案是输…

html <a>设置发送邮件链接、打电话链接 <a href=“mailto:></a> <a href=“tel:></a>

1.代码 <ul><li>电话&#xff1a;<a href"tel:18888888888">188-8888-8888</a></li><li>邮箱&#xff1a;<a href"mailto:10000qq.com">10000qq.com</a></li><li>邮箱&#xff1a;<a hre…

前端关于pptxgen.js个人使用介绍

官方文档链接:Quick Start Guide | PptxGenJS git地址&#xff1a;https://github.com/gitbrent/PptxGenJS/ 1. 安装命令 npm install pptxgenjs --save yarn add pptxgenjs 2. 示例demo import pptxgen from "pptxgenjs"; // 引入pptxgen // 1. Create a Presenta…

【机器人】机械臂位置、轨迹和转矩控制概要

仍旧以 RRR&#xff08;三连杆&#xff09;为例&#xff0c;实现控制&#xff0c;可以采用以下步骤。这里的控制包括 位置控制轨迹控制 轨迹跟踪控制&#xff0c; 具体根据应用需求选择。以下是实现 RRR 机械臂控制的完整过程&#xff1a; 1. 定义机器人模型 通过 Denavit-H…

Python tkinter写的《电脑装配单》和 Html版 可打印 可导出 excel 文件

Python版 样图&#xff1a; 说明书&#xff1a; markdown # 电脑配置单使用说明书 ## 一、软件简介 电脑配置单是一个用于创建和比较两套电脑配置方案的工具软件。用户可以选择各种电脑配件,输入数量和价格,软件会自动计算总金额,并支持导出和打印配置单。 ## 二、主要功能 1. …

android studio更改应用图片,和应用名字。

更改应用图标&#xff0c;和名字 先打开AndroidManifest.xml文件。 更改图片文件名字&#xff08; 右键-->构建-->重命名&#xff08;R&#xff09;&#xff09;

Vue Web开发(十)

1. 用户管理新增&#xff0c;搜索&#xff0c;编辑&#xff0c;删除 本节课完成用户列表表单设计&#xff0c;使用table组件&#xff0c;同样模块化组件&#xff0c;CommonTable.vue组件&#xff0c;并且在User页面中引入&#xff0c;mock实现数据模拟&#xff0c;最终完成用户…

人工智能在VR展览中扮演什么角色?

人工智能&#xff08;AI&#xff09;在VR展览中扮演着多重关键角色&#xff0c;这些角色不仅增强了用户体验&#xff0c;还为展览的组织者提供了强大的工具。 接下来&#xff0c;由专业从事VR展览制作的圆桌3D云展厅平台为大家介绍AI在VR展览中的一些主要作用&#xff1a; 个性…

学工管理系统-职校信息化管理平台

学工管理系统是一种致力于提升职校管理效率和信息化水平的重要工具。它综合运用了现代信息技术和学工管理理念&#xff0c;为学校提供了全面、科学、高效的管理平台。 学工管理系统在学校管理中发挥着重要的作用。它能够实现学生信息的完整管理&#xff0c;包括学籍、课程、成绩…

如何测量分辨率

一、什么是分辨率&#xff1f; 分辨率指的是分清物体细节的能力。分辨率是一个成像系统还原空间频率的能力。一些人只是简单的用分辨率去描述极限分辨率&#xff0c;但是相机在在不同的对比度的情况下还原低&#xff0c;中和高频率的能力&#xff0c;也可以显示全面综合的信息。…

MySQL数据库下载及安装教程

链接&#xff1a;MySQL数据库下载及安装教程&#xff08;最最新版&#xff09;_mysql下载安装-CSDN博客 亲测安装成功了&#x1f495; 把这个路径放到系统环境变量里头 MD!我这安到C盘去了&#xff0c;就很烦&#x1f92c;&#x1f621; 在CMD登录试一下 mysql -h localhos…