There is another way to do this other than try ... yield ... except : by introducing a new generator. With this class, you can convert all the inputs and outputs of your base generator:
identity = lambda x: x class map_generator: def __init__(self, generator, outfn = identity, infn = identity, throwfn = identity): self.generator = generator self.outfn = outfn self.infn = infn self.throwfn = throwfn self.first = True def __iter__(self): return self def __next__(self): return self.send(None) def _transform(self, value): if self.first: self.first = False return value else: return self.infn(value) def send(self, value): return self.outfn(self.generator.send(self._transform(value))) def throw(self, value): return self.outfn(self.generator.throw(self.throwfn(value))) def next(self):
Using:
def foo(): for i in "123": print("sent to foo: ", (yield i)) def bar(): dupe = lambda x:2*x tripe = lambda x:3*x yield from map_generator(foo(), dupe, tripe) i = bar() print("received from bar: ", i.send(None)) print("received from bar: ", i.send("B")) print("received from bar: ", i.send("C")) ... received from bar: 11 sent to foo: BBB received from bar: 22 sent to foo: CCC received from bar: 33
EDIT: you can inherit from collections.Iterator , but this is not necessary in this utility.
Tamas hegedus
source share