在Python中装饰生成器:在yield之间调用一些方法 [英] Decorating a generator in Python: call some method in between yields

查看:109
本文介绍了在Python中装饰生成器:在yield之间调用一些方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在这里使用来自收益。例如:

I found some very useful information about decorating generator functions in Python here using yield from. For example:

def mydec(func):
    def wrapper(*args, **kwargs):
        print(f'Getting values from "{func.__name__}"...')
        x = yield from func(*args, **kwargs)
        print(f'Got value {x}')
        return x
    return wrapper

@mydec
def mygen(n):
    for i in range(n):
        yield i

但是,这似乎仅允许在生成器的开头和结尾处添加修饰的行为寿命:

However, this seems to only allow for adding decorated behaviors at the beginning and end of the generator's lifetime:

>>> foo = mygen(3)
>>> x = next(foo)
Getting values from "mygen"...
>>> x
0
>>> x = next(foo)
>>> x
1
>>> x = next(foo)
>>> x
2
>>> x = next(foo)
Got value None
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
>>> x
2

但是,我有兴趣每次使用装饰器来实现某些行为发电机的产量。但是,装饰器不应修改从生成器获取的值。也就是说,例如,我想要输出:

However I am interested in using the decorator to implement some behavior every time the generator yields. However, the decorator should not modify the values that are gotten from the generator. That is, for example, I'd like to have the output:

>>> foo = mygen(3)
>>> x = next(foo)
Getting values from "mygen"...
Got value 0
>>> x
0
>>> x = next(foo)
Got value 1
>>> x
1
>>> x = next(foo)
Got value 2
>>> x
2

因此,调用 print 与每个收益率有关,但是收益率值保持不变。

So, a call to print occurs with each yield, however the yielded values remain unchanged.

这可能吗?

推荐答案

从$code>的收益用于协程物品。您不是在做协程的东西。只需迭代生成器:

yield from is for coroutine stuff. You're not doing coroutine stuff. Just iterating the generator:

def mydec(func):
    def wrapper(*args, **kwargs):
        print(f'Getting values from "{func.__name__}"...')
        gen = func(*args, **kwargs)
        for value in gen:
            print(f'got value {value}')
            yield value
    return wrapper

这篇关于在Python中装饰生成器:在yield之间调用一些方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆