Python中的Yield关键字

2025年1月4日 | 阅读7分钟

Python 中有许多工具使程序员的生活更加轻松。Python 中的 yield 关键字就是这样一个工具。在典型的 Python 进程中,这个关键字可以用来代替 return 语句。我们将介绍 yield 关键字,它在生成器函数中的使用,return 语句和 yield 语句的区别,以及可以在何种情况下使用 yield 语句代替 return 语句。

Python 中的 yield 关键字是什么?

Python 的 yield 关键字类似于我们用来返回一个表达式或对象的另一个关键字,通常在函数中使用,称为 return。但有一个微小的差异。函数中的 yield 语句返回的是一个生成器对象,而不是简单地将一个值返回给调用包含该语句的函数。

当程序调用函数时,Python 解释器在遇到 yield 语句时会暂停函数的执行。生成器类将一个对象返回给调用者。

换句话说,传递给 yield 关键字的任何表达式都将被转换为一个生成器对象,然后该对象将被返回给调用者。因此,为了获取这些值,我们必须反复访问生成器对象。

请注意,生成器函数是使用 yield 关键字定义的函数。局部变量的状态不会因 yield 关键字而丢失。每次调用函数时,最近的 yield 表达式都将作为执行的起点。

如果使用 return 语句调用函数,则每次都会创建新的变量。如果使用生成器函数代替普通函数,则函数的执行将从中断的地方继续。

为了通过一个函数返回多个值,我们可以结合使用生成器函数和 yield 关键字。yield 表达式返回多个值。它们返回一个值,暂停执行,保存指定变量的局部状态,然后恢复。

Python 中 yield 关键字的语法

Python 生成器函数概述

与只能返回单个表达式的 Python 中的常规函数不同,生成器函数返回一个可迭代对象,我们称之为生成器对象。我们可以通过简单的 Python 循环、next() 或 list() 等方法,或者通过生成器对象内部存储的变量,逐个访问或读取生成器函数中的值。我们使用 def 关键字创建生成器函数。下面的示例是一个很好的例子。

使用生成器函数的 yield 关键字示例

当我们调用这些函数时,会打印出特定的字符串。

代码

输出

<class 'generator'>
Yield
Keyword
in
Python

我们在程序中创建了一个简单的生成器函数,在使用了几个 yield 表达式来返回多个值之后,Python 将它们保存在我们创建的一个生成器对象中。然后,可以通过循环遍历该对象,在控制台上显示此生成器函数中的值。

对奇数进行排序,使用 yield 关键字

让我们创建一个全新的生成器函数,该函数使用 yield 命令。我们将尝试从一个整数列表中过滤掉奇数。必须使用多种方法(包括 list()、for-in 和 next())输出存储在生成器对象中的信息。

输出

[1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33]

如何调用带 yield 的函数?

使用 yield,我们可以调用函数,而不仅仅是返回一个值。例如,假设我们创建一个名为 square() 的函数,该函数在被调用时返回给定数字的平方。此代码使用了 return 关键字。另一个名为 square() 的函数使用 yield 关键字来提供一系列整数的平方。在这种情况下,我们可以将 yield 表达式与 square() 函数结合起来创建一个简单的程序。请看下面的示例代码。

代码

输出

[0, 1, 4, 9, 16, 25, 36, 49]

return 关键字与 yield 关键字的区别

Python 函数中的 yield 关键字与用于返回值的 return 关键字类似,不同之处在于使用 yield 关键字的生成器函数返回的是一个生成器对象,而不是单个值。它们的主要区别在于 Python 中的 return 关键字会终止函数的执行。然而,yield 关键字会暂停函数的执行。另一个区别是 return 关键字之后的语句永远不会被执行。当函数继续运行时,yield 语句会被执行。

何时使用 yield 而不是 return 关键字?

yield 关键字会暂停函数的执行,返回一个值,并保留足够的状态,以便生成器函数能够从 yield 离开的地方继续执行。当执行恢复时,函数将从上一个 yield 执行中断的地方继续执行。这使得程序能够随着时间的推移输出一系列值,而不是同时计算值并将它们作为列表数据类型返回。

使用 yield 的优点

  • 因为它保留了局部变量的状态,所以内存分配的负担得到了控制。
  • 由于保留了前一个状态,程序不必重新启动,这节省了时间。

使用 yield 的缺点

  • 函数必须正确调用。否则,有时使用 yield 可能会导致不准确。
  • 时间与存储优化导致编码复杂度增加,其原因通常难以捉摸。

输出

Function with return keyword:  3.0
Function with yield keyword:  [0.0, 1.0, 1.4142135623730951]

虽然 yield 关键字可以产生多个结果,但 return 只给调用者一个特定的值。如果我们想遍历一个序列但又不想将整个序列保存在内存中,则必须使用 yield。

Python 生成器函数使用 yield return 输出。当使用 def 关键字的生成器函数需要生成值时,使用 yield 关键字代替 return 关键字。当 yield 被包含在定义的正文中时,该函数就变成了一个生成器函数。

return 和 yield 关键字的区别列表

下面列出了 Python 中的 yield 和 return 之间的区别。

区别点产生的关键字返回关键字
定义当调用生成器函数时,yield 关键字返回的所有值会合并成一个生成器对象。代码要等到调用者通过该对象进行迭代后才开始运行。一旦到达 return 语句,函数执行就会终止,并且只会返回一个值给我们。
函数当我们调用生成器函数时,会执行第一个 yield,然后函数终止。之后,我们会收到一个包含 yield 返回值的生成器对象。当我们想要访问或迭代此变量时,下一个 yield 语句就会被执行,然后循环重复。当我们调用普通函数时,执行就开始了,当它到达 return 语句时结束。之后,我们会收到返回值。
每个函数的关键字数量我们可以在生成器函数中使用多个 yield 语句。一个普通函数只能使用一个 return 语句。
存储使用 yield 关键字时,无需分配任何存储空间。返回的每个值都会分配内存。
应用内存效率极高,尤其是在处理大型数据集时。此关键字应适用于较小的数据集。
执行使用 yield 关键字可以加快大型数据集的执行时间。由于需要更多的计算,更大的数据量会导致更长的执行时间。