Python @协程装饰器

Python @coroutine decorator

python是否内置了协程装饰器?我在 tornado 中看到过类似的东西,但是 python 中有类似这样的东西吗?

@coroutine
def func():
    while True:
        val = yield

这样我就可以立即调用它并 send,而无需先使用 next。我想一个基本的方法是:

def coroutine(func):
    @functools.wraps(func)
    def wrapper_coroutine(*args, **kwargs):
        f = func(*args, **kwargs)
        next(f)
        return f
    return wrapper_coroutine

但我想知道 python 是否在我缺少的地方内置了这个。

您可能已经自己回答了这个问题,但是为了遇到这个问题的其他人的利益,我一直在寻找同样的东西并找到了以下内容:

如评论中所述,简单的答案是;标准库中似乎没有这样的东西。

David Beazely 关于 coroutines and their application on this site point to an implementation of a @coroutine decorator 主题的回答,为方便起见,下面列出了其中的代码片段。

def coroutine(func):
    def start(*args,**kwargs):
        cr = func(*args,**kwargs)
        cr.next()
        return cr
    return start

回复@DocDriven的评论;上面是 David Beazely 实现的直接副本,它适用于 v3.2 之前的 Python 版本。已接受的答案 question 给出了更全面的解释和讨论,但是从 Python v3.2 开始,.next() 已被内置的自由函数 next() 取代。因此,当使用 Python 的 3.2 版及更高版本时,对 cr.next() 的调用将替换为对自由函数 next(cr).

的调用

更新 David Beazely 的原始实现以与 Python 版本 3.2 及更高版本一起使用,带有示例使用的完整代码变为:

def coroutine(func):
    def start(*args,**kwargs):
        cr = func(*args,**kwargs)
        next(cr)
        return cr
    return start

# Example use
if __name__ == '__main__':
    @coroutine
    def grep(pattern):
        print("Looking for %s" % pattern)
        while True:
            line = (yield)
            if pattern in line:
                print(line)

    g = grep("python")
    # Notice how you don't need a next() call here
    g.send("Yeah, but no, but yeah, but no")
    g.send("A series of tubes for pythons")
    g.send("python generators rock!")

这对我有用 Python v3.7.3