Украшение генератора в Python: вызовите некоторый метод между выходами - PullRequest
0 голосов
/ 31 августа 2018

Я нашел очень полезную информацию о декорировании функций генератора в Python здесь с использованием yield from. Например:

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

Однако, это, кажется, позволяет добавлять декорированные поведения в начале и в конце срока службы генератора:

>>> 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

Однако мне интересно использовать декоратор для реализации некоторого поведения каждый раз, когда генератор выдает. Однако декоратор не должен изменять значения, полученные от генератора. То есть, например, я бы хотел получить вывод:

>>> 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 происходит с каждой доходностью, однако полученные значения остаются неизменными.

Возможно ли это?

1 Ответ

0 голосов
/ 31 августа 2018

yield from для сопрограмм. Ты не делаешь сопрограммы. Просто итерация генератора:

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
...