Python中的yield

文章目录

    • 1. Python中的yield
      • 1.1 一个简单的示例
      • 1.2 示例的每一步含义
    • 2. yield 和return的区别
      • 2.1 一个简单的示例
      • 2.2 示例中每一步的含义
    • 3. yield中的send()方法
      • 3.1 一个简单的示例
      • 3.2 示例中每一步的含义
    • 4. yield中的throw()方法
      • 4.1 一个简单的示例
      • 4.2 示例中每一步的含义

1. Python中的yield

yield 是 Python 中用于创建生成器的关键字之一。它可以在函数内部暂停执行并返回一个值,但是保留了函数的状态,使得函数可以在后续调用时恢复执行,从上次暂停的地方继续执行。这种特性使得生成器可以逐步产生值,而不需要一次性将所有值存储在内存中,从而节省了内存空间。

1.1 一个简单的示例

我们可以通过一个简单的示例来说明 yield 的使用:

def count_up_to(limit):
    count = 1
    while count <= limit:
        yield count
        count += 1

# 创建一个生成器对象
counter = count_up_to(5)

# 逐步获取生成器产生的值并打印
print(next(counter))  # 输出:1
print(next(counter))  # 输出:2
print(next(counter))  # 输出:3
print(next(counter))  # 输出:4
print(next(counter))  # 输出:5

1.2 示例的每一步含义

  1. def count_up_to(limit)::这是一个生成器函数的定义,它命名为 count_up_to,接受一个参数 limit,用于指定计数的上限。
  2. count = 1:这是计数器的初始化,从 1 开始计数。
  3. while count <= limit::这是一个循环,它会在计数小于等于上限时持续执行。
  4. yield count:这是 yield 语句,它会产生当前计数值并暂停函数的执行。在每次迭代中,生成器会生成一个值并将控制权返回给调用方。
  5. count += 1:这是计数器的增加步骤,每次迭代时,计数器增加 1。
  6. counter = count_up_to(5):这里创建了一个生成器对象,调用 count_up_to() 函数并将其赋值给变量 counter
  7. print(next(counter)):在生成器对象上调用 next() 函数,这会使生成器函数从上次暂停的地方继续执行,生成并返回下一个计数值。

通过 yield,我们可以实现一个能够逐步产生数值的生成器函数。这个函数在每次迭代时都会生成一个值并暂停执行,直到下一次迭代开始。这种逐步生成值的方式非常高效,特别是在处理大量数据或无限序列时。

2. yield 和return的区别

yieldreturn 在 Python 中有着不同的作用,尽管它们都可以用于函数中的值的返回,但它们之间有着关键的区别。

2.1 一个简单的示例

让我们通过一个示例来说明它们的区别:

def generator_with_yield():
    yield 1
    yield 2
    yield 3

def function_with_return():
    return [1, 2, 3]

# 使用生成器函数
gen = generator_with_yield()
print(next(gen))  # 输出:1
print(next(gen))  # 输出:2
print(next(gen))  # 输出:3

# 使用普通函数
result = function_with_return()
print(result)  # 输出:[1, 2, 3]

2.2 示例中每一步的含义

  1. def generator_with_yield()::这是一个生成器函数的定义。它使用 yield 语句产生值。在每次调用 next() 时,函数会执行到下一个 yield 语句,生成一个值并暂停执行,直到下一次调用。
  2. def function_with_return()::这是一个普通函数的定义。它使用 return 语句来返回一个列表。
  3. gen = generator_with_yield():这里创建了一个生成器对象,调用 generator_with_yield() 函数并将其赋值给变量 gen
  4. print(next(gen)):在生成器对象上调用 next() 函数,这会使生成器函数从头开始执行,生成第一个值并返回。每次调用 next(),生成器函数都会继续执行,直到遇到下一个 yield 语句为止。
  5. result = function_with_return():在普通函数上调用,它会执行函数内部的代码,生成并返回一个列表。
  6. print(result):打印普通函数的返回值,这是一个包含 [1, 2, 3] 的列表。

关键区别:

  • yield 可以在生成器函数中多次返回值,并且函数的状态会被保留,可以在后续调用中恢复执行。这使得生成器函数可以实现惰性计算和逐步生成值的功能。
  • return 一旦执行,会立即结束函数的执行,并将一个值返回给调用方。函数的状态不会被保留,无法恢复执行。

总的来说,yield 用于创建生成器函数,支持暂停和恢复执行,而 return 用于普通函数,用于一次性返回值并终止函数执行。

3. yield中的send()方法

在 Python 的 yield 中,send() 是一种方法,它允许在生成器函数内部发送数据,并使生成器继续执行。这种方法可以用于在生成器的每次迭代中向其提供值,以及控制生成器的行为。

3.1 一个简单的示例

下面是一个简单的示例,演示了如何在生成器函数中使用 send() 方法:

def accumulator():
    total = 0
    while True:
        value = yield total
        if value is not None:
            total += value

# 创建一个生成器对象
acc_gen = accumulator()

# 启动生成器
next(acc_gen)

# 使用 send() 方法向生成器发送值并获取结果
print(acc_gen.send(1))  # 输出:1
print(acc_gen.send(2))  # 输出:3
print(acc_gen.send(3))  # 输出:6

3.2 示例中每一步的含义

  1. def accumulator()::这是一个生成器函数的定义,命名为 accumulator。它没有参数。
  2. total = 0:这是累加器的初始化,开始时总和为 0。
  3. while True::这是一个无限循环,表示生成器函数会一直执行,直到外部调用方主动关闭生成器。
  4. value = yield total:这是 yield 语句,它会生成当前的总和值,并暂停函数的执行。在每次迭代中,生成器会生成一个值并将控制权返回给调用方。同时,它也是一个接收来自外部的值的地方,通过 send() 方法向生成器发送值。
  5. if value is not None::这是一个条件语句,检查发送的值是否为 None,如果不是 None,则表示有新的值要累加到总和中。
  6. total += value:这是将新值累加到总和中的步骤。
  7. acc_gen = accumulator():这里创建了一个生成器对象,调用 accumulator() 函数并将其赋值给变量 acc_gen
  8. next(acc_gen):这是启动生成器的步骤,通过 next() 函数开始执行生成器函数,使其执行到第一个 yield 语句处暂停。
  9. print(acc_gen.send(1)):在生成器对象上调用 send() 方法,发送值 1 给生成器,并获取生成器生成的总和值。

通过 send() 方法,我们可以在生成器的每次迭代中向其提供值,并控制生成器的行为。这种方法使得生成器函数更加灵活,可以与外部环境进行双向通信。

4. yield中的throw()方法

在 Python 的 yield 中,throw() 是一种方法,它允许在生成器函数内部抛出一个指定的异常,并使生成器处理该异常。这种方法可以用于在生成器函数中处理错误或特定情况,并根据需要采取相应的行动。

4.1 一个简单的示例

下面是一个简单的示例,演示了如何在生成器函数中使用 throw() 方法:

def catcher():
    try:
        while True:
            try:
                value = yield
                print("Received:", value)
            except ValueError as ve:
                print("ValueError occurred:", ve)
    except GeneratorExit:
        print("Generator closed.")

# 创建一个生成器对象
gen = catcher()
next(gen)  # 启动生成器

# 在生成器中抛出异常
gen.throw(ValueError("Invalid value"))

# 继续在生成器中发送值
gen.send(10)

# 关闭生成器
gen.close()

4.2 示例中每一步的含义

  1. def catcher()::这是一个生成器函数的定义,命名为 catcher。它没有参数。
  2. try::这是一个 try 块,表示生成器函数会尝试执行其中的代码。
  3. while True::这是一个无限循环,表示生成器函数会一直执行,直到外部调用方主动关闭生成器。
  4. try::这是内部的 try 块,用于捕获可能在 yield 语句周围发生的异常。
  5. value = yield:这是 yield 语句,它会暂停函数的执行,并等待外部发送的值。在每次迭代中,生成器会生成一个值并将控制权返回给调用方。
  6. except ValueError as ve::这是一个 except 块,用于捕获特定类型的异常(在这里是 ValueError)。
  7. print("Received:", value):这是打印接收到的值的步骤。
  8. except GeneratorExit::这是一个特殊的 except 块,用于捕获生成器关闭时的异常。
  9. gen = catcher():这里创建了一个生成器对象,调用 catcher() 函数并将其赋值给变量 gen
  10. next(gen):这是启动生成器的步骤,通过 next() 函数开始执行生成器函数,使其执行到第一个 yield 语句处暂停。
  11. gen.throw(ValueError("Invalid value")):在生成器对象上调用 throw() 方法,抛出一个 ValueError 异常。
  12. gen.send(10):继续在生成器中发送值,这里发送了一个整数值 10。
  13. gen.close():关闭生成器,这将导致生成器函数抛出 GeneratorExit 异常,生成器函数中的相应代码将被执行。

通过 throw() 方法,我们可以在生成器函数中抛出异常,并根据需要进行处理。这种方法使得生成器函数更加灵活,可以在生成器内部处理错误或特定情况。

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

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

相关文章

【vue+echarts】绘制中国地图,3D地图,省、市、县三级下钻以及回钻,南海诸岛小窗化显示,点位飞线图,点位名称弹窗轮播展示,及一些常见问题

先看效果展示图 目录 准备工作一, 绘制3D地图1,调用官网地址接口获取2,去官网下载中国地图的json数据到本地,本地引入 二, 南海诸岛小窗化显示1, 手动过滤掉,只保留小窗化的南海诸岛2, 代码层面过滤掉,只保留小窗化的南海诸岛 三, 省、市、县三级地图下钻及回钻1, 下钻2, 回钻…

YApi的在IDEA中的使用

1 IDEA中插件下载 2 misc.xml的配置 <component name"yapi"><option name"projectToken">XXXXXXXXXX</option><option name"projectId">47</option><option name"yapiUrl">http://XXXX:3000<…

第10篇:创建Nios II工程之控制单个七段数码管

Q&#xff1a;还记得之前使用Verilog case语句来描述实现七段数码管的逻辑功能。本期我们创建Nios II工程用C语言代码实现相同的功能。 A&#xff1a;基本原理&#xff1a;一个七段数码管由7个发光二极管LED组成&#xff0c;所以控制一个数码管的显示即控制7个LED。我们在之前…

效率工具Cmder与文件拆分

Cmder安装&#xff1a; 网站下载&#xff0c;解压缩&#xff0c;使用管理员身份打开Cmder可执行程序。 Cmder鼠标右键快捷点打开设置 样式图&#xff1a; 命令&#xff1a;以管理员的身份打开Cmder.exe, 输入命令: Cmder.exe /REGISTER ALL 执行完之后回到桌面&#xff0c;…

linux查看ip和端口

1. ip addr ip addr 或者 ip addr show 输出包含了网络接口的名称、状态、MTU&#xff08;Maximum Transmission Unit&#xff09;、链路层地址&#xff08;如MAC地址&#xff09;、IPv4和IPv6地址等信息。 2. 只需要 ip地址 ipV4 ip addr | grep inet ipV6 3.查看端口 s…

国内外主流大模型都具备有哪些特点?

文章目录 ⭐ 火爆全网的大模型起点⭐ 国外主流LLM及其特点⭐ 国内主流LLM及其特点⭐ 全球大模型生态的发展 该章节呢&#xff0c;我们主要是看一下关于国内外主流的大语言模型&#xff0c;通过它们都具备哪些特点&#xff0c;来达成对多模型有一个清晰的认知。对于 “多模型” …

python从0开始学习(三)

目录 前言 1、类型转换 1.1 隐式类型转换 1.2 显式类型转换 2、eval函数 总结 前言 上篇我们讲了python中的变量与常量&#xff0c;以及变量类型。本篇文章将接着往下讲。 1、类型转换 python中的数据类型转换包括两种&#xff1a;隐式类型转换和显式类型转换。 1.1 隐式…

数据库开发关键之与DQL查询语句有关的两个案例

案例 案例1 条件分页查询 查看项目经理提供给我们的需求文档 模糊匹配的含义是 只要包含"张"就可以 use dduo;-- 按照需求完成员工管理的条件分页查询 根据输入条件 查询第一页的数据 每页展示10条记录 -- 输入条件&#xff1a; -- 姓名&#xff1a; 张 -- 年龄&…

JavaScript之数据类型(1)

数据类型的分类&#xff1a; 我们可以将数据类型分为简单数据类型&#xff0c;复杂数据类型。 简单数据类型&#xff1a; 简介&#xff1a; 数据类型说明默认值Number数字型&#xff0c;包含 整型值和浮点型值&#xff0c;如 21、0.210Boolean布尔值类型&#xff0c;如 true、…

防泄密,防飞单!好用的企业电脑监控软件推荐

公司辛辛苦苦维护的客户被竞争对手抢先 成本报价被窃取&#xff0c;公司失去先机…… 员工泄露公司数据和飞单问题一直是企业面临的重要挑战。这些行为不仅可能导致企业遭受重大的经济损失&#xff0c;还可能损害企业的声誉和客户关系。因此&#xff0c;企业需要采取一系列措…

19_Scala集合概述

文章目录 集合回顾javaScala集合三大类String & StringBuilderScala集合两大类 集合 回顾java scala与Java有所不同 函数式编程语言更侧重集合本身提供的哪些功能&#xff1b; Scala集合三大类 1.Seq 存储有序数据可重复 类比 List 2.Set 存储无序数据不可重复 3.Map…

ttkbootstrap界面美化系列之Menubutton(五)

一&#xff1a;Menubutton接口 print(help(help(ttk.Menubutton))) Help on class Menubutton in module tkinter.ttk:class Menubutton(Widget)| Menubutton(masterNone, **kw)|| Ttk Menubutton widget displays a textual label and/or image, and| displays a menu wh…

【MySQL】第一次作业

【MySQL】第一次作业 1、在官网下载安装包2、解压安装包&#xff0c;创建一个dev_soft文件夹&#xff0c;解压到里面。3、创建一个数据库db_classes4、创建一行表db_hero5、将四大名著中的常见人物插入这个英雄表 写一篇博客&#xff0c;在window系统安装MySQL将本机的MySQL一定…

spring源码分析之AOP开启注解

AOP开启注解 在使用注解Aspect来进行AOP操作时&#xff0c;需要在xml中进行配置 <!-- 使Aspect注解生效 --><aop:aspectj-autoproxy/> 创建BeanFactory时obtainFreshBeanFactory()在解析xml加载BeanDefinition中&#xff0c;执行parseBeanDefinitions方法进行解析发…

指挥中心操作台的选择至关重要

在指挥中心的环境中&#xff0c;操作台是核心设备&#xff0c;它承载着信息收集、处理、分发的重要任务。其选择应考虑到多方面的因素&#xff0c;包括外观、材质、稳定性、操作便利性以及技术支持等。嘉德立在这里给大家详细的总结一下选择指挥中心操作台的要点。 首先&#x…

5.Spring Security-web权限方案

设置登录的用户名和密码 1.通过配置文件设置用户名密码 spring:security:user:name: xiankejinpassword: 123456 如果没有以上配置&#xff0c;那么就会在后台生成一个随机密码&#xff0c;用户名固定位user。 2.通过配置类设置用户名密码 Configuration public class Sec…

【AIGC】深入探索AIGC技术在文本生成与音频生成领域的应用

&#x1f680;文章标题 &#x1f680;AIGC之文本生成&#x1f680;应用型文本生成&#x1f680;创作型文本生成&#x1f680;文本辅助生成&#x1f680;重点关注场景 &#x1f680;音频及文字—音频生成&#x1f680;TTS(Text-to-speech)场景&#x1f680;乐曲/歌曲生成&#x…

给股东送酱的公司值得关注吗?仲景食品-300908 年报分析(20240505)

仲景食品-300908 基本情况 公司名称&#xff1a;仲景食品股份有限公司 A股简称&#xff1a;仲景食品 成立日期&#xff1a;2002-09-29 上市日期&#xff1a;2020-11-23 所属行业&#xff1a;食品制造业 周期性&#xff1a;0 主营业务&#xff1a;调味配料和调味食品的研发、生产…

Android 14 变更及适配攻略

准备工作 首先将我们项目中的 targetSdkVersion和compileSdkVersion 升至 34。 影响Android 14上所有应用 1.最低可安装的目标 API 级别 从 Android 14 开始&#xff0c;targetSdkVersion 低于 23 的应用无法安装。要求应用满足这些最低目标 API 级别要求有助于提高用户的安…

跟TED演讲学英文:Is your partner “the one?“ Wrong question by George Blair-West

Is your partner “the one?” Wrong question Link: https://www.ted.com/talks/george_blair_west_is_your_partner_the_one_wrong_question Speaker: George Blair-West Date: December 2022 文章目录 Is your partner "the one?" Wrong questionIntroduction…
最新文章