深入理解Python生成器与yield表达式
本文深入解析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表达式的介绍即为全部内容,希望能对读者有所帮助,也欢迎大家继续支持本站。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









