However, I would like to make my reuse criteria one step harder: what if I need a governance structure around my re-generation?
itertools often helps even there - you need to provide specific examples where you think it is not.
For example, I could call a subgenerator forever with different parameters.
itertools.chain.from_iterable .
Or my warders can be very expensive, and I just want to launch them when and when they reached.
Both chain and chain_from_iterable do this - no sub-iterator is started until the very moment when the first element from it is required.
Or (and this is a real desire) I may need to change what I do next depending on what my controller passes me using send ().
A particular example should be particularly appreciated. In any case, in the worst case, you will encode for x in blargh: yield x , where a paused Pep3080 will allow you to encode yield from blargh - about 4 additional characters (not tragedy yield from blargh .
And if some complicated version of coroutine of some itertools functions (itertools mainly supports iterators - there is no equivalent coroutools module there) becomes justified, since a certain structure of coroutine composition is often repeated in your code, then it is not too complicated code itself.
For example, suppose we often do something like: first we get a certain value; then, again, if we sent "foo", you will get the next element from fooiter, if "bla", from blater, if "zop", from zopiter, anything else, from the customer. As soon as we notice the second appearance of this compositional drawing, we can encode:
def corou_chaiters(initsend, defiter, val2itermap): currentiter = iter([initsend]) while True: val = yield next(currentiter) currentiter = val2itermap(val, defiter)
and call this simple compositional function as needed. If we need to compile other coroutines, rather than general iterators, we will have a slightly different composer using the send method instead of the next built-in function; etc.
If you can offer an example that is not easy to tame by such methods, I suggest you do this in a separate question (specially designed for coprocessor generators), since there is already a lot of material on it that will have little to do your other, much more complicated / complicated one, example.