从返回值修改收益率

Bha*_*rel 7 python generator python-3.x yield-from

假设我有这些解析器:

parsers = {
    ".foo": parse_foo,
    ".bar", parse_bar
}
Run Code Online (Sandbox Code Playgroud)

parse_foo并且parse_bar都是逐个产生行的生成器.如果我想创建一个调度函数,我会这样做:

def parse(ext):
    yield from parsers[ext]()
Run Code Online (Sandbox Code Playgroud)

语法的收益使我能够轻松地在生成器上下传递信息.

有没有办法在修改产量结果的同时保持隧道效应?
在破坏隧道时这样做很容易:

def parse(ext):
    for result in parsers[ext]():
        # Add the extension to the result
        result.ext = ext
        yield result
Run Code Online (Sandbox Code Playgroud)

但这种方式我无法使用.send().throw()一直到解析器.

我想到的唯一方法是做一些丑陋的事情try: ... except Exception: ...并将异常传递出去,同时做同样的事情.send().它很难看,很杂乱,容易出错.

Bha*_*rel 0

不幸的是没有内置的可以做到这一点您可以使用类自己实现它,但名为cotoolz的包实现了一个map()完全可以实现此目的的函数。

他们的映射函数比内置函数慢 4 倍map(),但它了解生成器协议,并且比类似的 Python 实现更快(它是用 C 编写的,需要 C99 编译器)。

他们页面上的一个例子:

>>> def my_coroutine():
...     yield (yield (yield 1))
>>> from cotoolz import comap
>>> cm = comap(lambda a: a + 1, my_coroutine())
>>> next(cm)
2
>>> cm.send(2)
3
>>> cm.send(3)
4
>>> cm.send(4)
Traceback (most recent call last):
    ...
StopIteration
Run Code Online (Sandbox Code Playgroud)