Python中的yield

embedded/2024/9/22 14:57:48/

文章目录

    • 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 = 1while count <= limit:yield countcount += 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 1yield 2yield 3def 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 = 0while True:value = yield totalif 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 = yieldprint("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.ppmy.cn/embedded/34398.html

相关文章

如何提高硬件原理图设计的可读性和可维护性

硬件原理图设计是电子系统设计的重要一环&#xff0c;对于提高设计的可读性和可维护性至关重要。好的原理图设计不仅方便设计人员理解和修改&#xff0c;还能为后续的生产、测试和维护工作提供便利。以下是关于如何提高硬件原理图设计可读性和可维护性的几点建议&#xff1a; …

vue快速入门(五十四)$nextTick的使用

注释很详细&#xff0c;直接上代码 上一篇 新增内容 $nextTick的使用场景演示 源码 App.vue <template><div id"app"><h3>{{name}}</h3><button click"showfixed">修改</button><form action"post" v-s…

【网络】传输层的特点总结

1传输层协议 传输层主要有两个常见的协议&#xff1a;TCP&#xff08;传输控制协议&#xff09;和UDP&#xff08;用户数据报协议&#xff09;。TCP 提供可靠的、面向连接的通信服务&#xff0c;适用于对数据传输可靠性要求高的场景&#xff0c;如网页浏览、文件传输等。而 UD…

校园餐厅预约系统(请打开git自行访问)

校园餐厅预约系统详细介绍 项目地址&#xff1a;https://gitee.com/zhang—xuan/online_booking_system 服务端部分 Socket类 作用&#xff1a;创建socket连接&#xff0c;作为服务端与客户端通信的基础。 Sock_Obj类 基类&#xff1a;定义了服务端需要的基本操作和属性。 派生…

MySQL多表查询

建表准备&#xff0c;建表时有的数据库可能需要指定字符集&#xff0c;所以需要加这么一段&#xff0c;反正我这里是需要加了才能建表的 ✈每个查询都自己去敲&#xff0c;实超性的东西必须要自己动手&#xff0c;光看没用&#xff01;&#xff01;&#xff01; CHARACTER SE…

03-构建xss漏洞环境

先完成发帖的功能 1、前端代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><script type"text/java…

clang:在 Win10 上编译 MIDI 音乐程序(二)

先从 Microsoft C Build Tools - Visual Studio 下载 1.73GB 安装 "Microsoft C Build Tools“ 访问 Swift.org - Download Swift 找到 Windows 10&#xff1a;x86_64 下载 swift-5.10-RELEASE-windows10.exe 大约490MB 建议安装在 D:\Swift\ &#xff0c;安装后大约占…

基于springboot实现图书电子商务网站系统项目【项目源码+论文说明】

基于springboot实现图书电子商务网站系统演示 摘要 社会发展日新月异&#xff0c;用计算机应用实现数据管理功能已经算是很完善的了&#xff0c;但是随着移动互联网的到来&#xff0c;处理信息不再受制于地理位置的限制&#xff0c;处理信息及时高效&#xff0c;备受人们的喜爱…