深入理解Python生成器与yield表达式

Jasper
Jasper
发布时间:2026-10-13 | 6人浏览过
原创

本文深入解析Python中生成器与yield表达式的核心机制。yield不仅是语句更是表达式,支持赋值操作。通过next()和send()函数可控制生成器暂停与恢复,这是实现协程的基础。文章结合生产者消费者模型及具体代码示例,详细演示了send()需先初始化及参数传递赋值的完整过程,帮助开发者掌握高效内存管理的迭代技巧。

Python生成器基础

Python生成器

在Python中,生成器是迭代器的一种实现形式,主要利用yield关键字来返回函数值。每当执行到yield时,函数会暂停执行并保存当前状态;随后可以通过调用next()函数或send()函数来恢复生成器的执行流程。

如需对生成器进行更全面的了解,可参考Python函数式编程指南中关于生成器的详细讲解。

yield表达式的特性

值得注意的是,yield是一个表达式而不仅仅是一条语句,因此支持类似x = yield r这样的赋值语法结构。

协程与生成器的应用

这一特性在协程的实现中至关重要。协程的概念是指在一个线程内,程序执行过程中断并切换到另一个子程序,类似于CPU的中断机制。这种方式减少了线程切换带来的开销,且由于不存在多线程并发写入的问题,因此无需使用锁机制。

生产者消费者模型示例

Python利用生成器来实现协程功能,下面通过一个生产者消费者问题的示例来展示Python协程的具体应用。


def consumer():
 r = 'yield'
 while True:
  #当下边语句执行时,先执行yield r,然后consumer暂停,此时赋值运算还未进行
  #等到producer调用send()时,send()的参数作为yield r表达式的值赋给等号左边
  n = yield r #yield表达式可以接收send()发出的参数
  if not n:
   return
  print('[CONSUMER] Consuming %s...' % n)
  r = '200 OK'

def produce(c):
 c.send(None)
 n = 0
 while n < 5:
  n = n + 1
  print('[PRODUCER] Producing %s...' % n)
  r = c.send(n) #调用consumer生成器
  print('[PRODUCER] Consumer return: %s' % r)
 c.close()

c = consumer()
produce(c)

在使用send()方法前,必须先调用send(None)进行初始化,因为只有当生成器处于暂停状态时,才能接收send()发送的参数。

send()恢复生成器详解

为了更清晰地理解send()如何恢复生成器的执行过程,我们可以参考以下代码示例:


def gen():
 a = yield 1
 print('yield a % s' % a)
 b = yield 2
 print('yield b % s' % b)
 c = yield 3
 print('yield c % s' % c)


r = gen()
x = next(r)
print('next x %s' % x)
y = r.send(10)
print('next y %s' %y)
z = next(r)
print('next z %s' % z)

从运行结果可以看出,实际上y=r.send(10)中的参数10被赋值给了变量a。整个执行流程为:首先执行x=next(r),此时gen()函数执行yield 1后暂停,尚未对a进行赋值;但当再次调用y=r.send(10)时,赋值过程继续,并将10赋给了a。

以上关于Python中yield表达式的介绍即为全部内容,希望能对读者有所帮助,也欢迎大家继续支持本站。

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表