Python 中的 yield 是什么

写在前面

Python 中的 yield 关键字是一个我们不太常见的关键字, 但它却拥有非常强大的功能。 yield 可以让我们在函数中实现生成器(generator)的功能, 从而带来更多编程上的便利。在本文中, 我们将深入探讨 yield 的使用方法, 以及它与 return 关键字的区别。通过学习 yield, 相信你会发现 Python 语言的无穷魅力。

生成器与迭代器

在讨论 yield 之前, 我们需要先了解生成器(generator)和迭代器(iterator)的概念。迭代器是一个实现了迭代器协议的对象, 它可以逐个返回序列中的元素。生成器是一种特殊的迭代器, 它使用 yield 关键字定义, 能够暂停和恢复函数的执行状态。生成器函数可以产生一个迭代器对象, 从而实现仅在需要时生成数据的功能。

yield 语句的基本用法

yield 语句的使用方法相当简单。在函数中使用 yield 关键字, 可以让函数变成一个生成器。每次调用生成器函数, 它都会返回 yield 语句后的值, 并保存函数的执行状态。下次调用时, 函数会从上次yield 的位置继续执行, 直到遇到下一个 yield 语句。例如:

def count_up_to(n):
    i = 0
    while i < n:
        yield i
        i += 1

generator = count_up_to(5)
print(next(generator))  # 输出: 0
print(next(generator))  # 输出: 1
print(next(generator))  # 输出: 2
print(next(generator))  # 输出: 3
print(next(generator))  # 输出: 4
print(next(generator))  # 抛出 StopIteration 异常

生成器函数

生成器函数是使用 yield 关键字定义的函数。与普通函数不同, 生成器函数在每次 yield 时都会暂停执行, 并返回一个中间结果。当下次调用生成器函数时, 它会从上次暂停的地方继续执行, 直到遇到下一个 yield 语句。这种”惰性求值”的特性使生成器函数非常适合处理大量或无限的数据集。下面是一个生成斐波那契数列的例子:

def fibonacci(n):
    a, b = 01
    for i in range(n):
        yield a
        a, b = b, a + b

fib = fibonacci(10)
for num in fib:
    print(num)
# 输出: 0 1 1 2 3 5 8 13 21 34

yield 与 return 的区别

听到这里,可能有小伙伴觉得这个 yield 和 函数的 return 很像,那么它们到底有什么不同呢?虽然,yield 和 return 都可以返回值, 但二者有着本质的区别。让我们来对比一下:

首先,使用 return 和 yield 定义两个函数如下:

def square_return(n):
    squares = []
    for i in range(n):
        squares.append(i**2)
    return squares

def square_yield(n):
    for i in range(n):
        yield i**2

调用square_return函数

# 使用 return 的版本
print(square_return(5))  # 输出: [0, 1, 4, 9, 16]

调用square_yield函数

# 使用 yield 的版本
square_gen = square_yield(5)
print(next(square_gen))  # 输出: 0
print(next(square_gen))  # 输出: 1
print(next(square_gen))  # 输出: 4
print(next(square_gen))  # 输出: 9
print(next(square_gen))  # 输出: 16
print(next(square_gen))  # 抛出 StopIteration 异常

正如你所见, return 会立即终止函数的执行, 而 yield 只是暂时返回一个值, 函数的状态会被保存下来。

迭代器协议与惰性求值

生成器函数实现了迭代器协议, 可以作为可迭代对象使用。迭代器协议要求对象实现 iter() 和 next() 方法。生成器函数隐式地实现了这两个方法, 因此可以作为迭代器使用。生成器函数的另一个重要特性是惰性求值, 它只在需要时才生成数据, 这对于处理大量或无限数据非常有利。

常见应用场景

yield 关键字在 Python 中有许多常见的应用场景, 包括:

  1. 生成无限序列, 如斐波那契数列、素数序列等。
  2. 处理大数据集, 通过惰性求值避免内存溢出。
  3. 实现协程, 利用 yield 实现并发任务的切换。
  4. 构建自定义的迭代器, 满足特定的需求。

写在最后

在本文中, 我们详细探讨了 Python 中 yield 关键字的用法和特性。yield 可以让函数变成生成器, 实现数据的惰性求值和双向通信。通过学习 yield, 我们不仅能编写更加简洁和高效的代码, 还能发现 Python 语言的无穷魅力。让我们一起探索 yield 的更多应用吧!


原文始发于微信公众号(harvey的网络日志):Python 中的 yield 是什么

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/259487.html

(0)
服务端技术精选的头像服务端技术精选

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!