lundi 20 février 2023

pythonic way to decorate an iterator at run-time?

I have the following code:

def assertfilter(iterator, predicate):
    # TODO support send()
    for result in iterator:
        if not predicate(result):
            raise AssertionError("predicate failed in assertfilter()")
        yield result

Any attempt I could come up with to refactor it to support send() seems to look horrifically convoluted, unreadable, and non-obvious:

def assertfilter(iterator, predicate):
    result = None
    while True:
        try:
            sent = yield result
            if sent is not None:
                result = iterator.send(sent)
            else:
                result = next(iterator)
            if not predicate(result):
                raise AssertionError("predicate failed in assertfilter()")
        except StopIteration:
            return

Is there a recognized, common, readable way to inject/wrap logic onto an existing iterator? Or is the above the best-practice currently?

Aucun commentaire:

Enregistrer un commentaire