什么是pre-pumped generator coroutine?请解析示例代码运行方式
预激生成器协程(Pre-pumped Generator Coroutine)是什么?
概念定义
预激生成器协程指的是创建后立即完成「预激(priming)」操作的生成器。
在Python中,普通的生成器协程(用yield接收输入的生成器)刚创建时处于初始暂停状态,还未执行任何代码。要让它准备好接收数据,必须先调用一次next(),把生成器推进到第一个yield语句处——这个步骤就是「预激」。而预激生成器协程会自动完成这一步,创建后可以直接用send()发送数据,无需手动调用next()。
示例代码解析
你看到的代码是James Powell用一行lambda实现的预激装饰器,本质是把「创建生成器+预激」的步骤合并成一个调用。先修正代码里的递归问题(原代码用c(*a, **kw)会触发无限递归,应该用装饰器接收的原始函数x),再拆解逻辑:
@lambda x: lambda *a, **kw: (ci := x(*a, **kw), next(ci))[0] def c(*, mode): data = yield
运行步骤:
- 装饰器逻辑:
外层lambda接收原始生成器函数c作为参数x,返回一个新的lambda函数作为包装器。 - 调用
c(mode="xxx")时:ci := x(*a, **kw):调用原始函数x(未装饰的c)创建生成器实例,赋值给ci。next(ci):预激生成器,运行到data = yield处暂停,此时生成器已准备好接收数据。- 返回元组的第一个元素
ci——即预激完成的生成器实例。
- 使用生成器:
现在可以直接发送数据,无需手动预激:gen = c(mode="test") gen.send("hello world") # 数据会被赋值给生成器内的`data`变量
等价的可读性版本
James的代码是极简写法,和下面的普通装饰器功能完全一致:
def pre_pump(func): def wrapper(*args, **kwargs): gen = func(*args, **kwargs) next(gen) return gen return wrapper @pre_pump def c(*, mode): data = yield
内容的提问来源于stack exchange,提问作者Mnng
相关产品推荐
相关产品推荐

