chainlet.genlink module¶
Helpers for creating ChainLinks from generators
Tools of this module allow writing simpler code by expressing functionality via generators. The interface to other chainlet objects is automatically built around the generator. Using generators in chains allows to carry state between steps.
A regular generator can be directly used by wrapping GeneratorLink
around it:
from collections import deque
from mylib import producer, consumer
def windowed_average(size=8):
buffer = collections.deque([(yield)], maxlen=size)
while True:
new_value = yield(sum(buffer)/len(buffer))
buffer.append(new_value)
producer >> GeneratorLink(windowed_average(16)) >> consumer
If a generator is used only as a chainlet, one may permanently convert it by applying a decorator:
from collections import deque
from mylib import producer, consumer
@genlet
def windowed_average(size=8):
# ...
producer >> windowed_average(16) >> consumer
-
class
chainlet.genlink.
GeneratorLink
(slave, prime=True)¶ Bases:
chainlet.wrapper.WrapperMixin
,chainlet.chainlink.ChainLink
Wrapper making a generator act like a ChainLink
Parameters: - slave – the generator instance to wrap
- prime (bool) – advance the generator to the next/first yield
Note: Use the
genlet()
function if you wish to decorate a generator function to produce GeneratorLinks.This class wraps a generator, using it to perform work when receiving a value and passing on the result. The
slave
can be any object that implements the generator protocol - the methodssend
,throw
andclose
are directly called on theslave
.-
chainlet_send
(value=None)¶ Send a value to this element for processing
-
close
()¶ Close this element, freeing resources and blocking further interactions
-
throw
(type, value=None, traceback=None)¶ Raise an exception in this element
-
class
chainlet.genlink.
StashedGenerator
(generator_function, *args, **kwargs)¶ Bases:
object
A generator iterator which can be copied/pickled before any other operations
Parameters: - generator_function (function) – the source generator function
- args – positional arguments to pass to
generator_function
- kwargs – keyword arguments to pass to
generator_function
This class can be used instead of instantiating a generator function. The following two calls will behave the same for all generator operations:
my_generator(1, 2, 3, foo='bar') StashedGenerator(my_generator, 1, 2, 3, foo='bar')
However, a
StashedGenerator
can be pickled and unpickled before any generator operations are used on it. It explicitly disallows pickling afternext()
,send()
,throw()
orclose()
.def parrot(what='Polly says %s'): value = yield while True: value = yield (what % value) simon = StashedGenerator(parrot, 'Simon says %s') simon2 = pickle.loads(pickle.dumps(simon)) next(simon2) print(simon2.send('Hello')) # Simon says Hello simon3 = pickle.loads(pickle.dumps(simon2)) # raise TypeError
-
close
() → raise GeneratorExit inside generator.¶
-
next
() → the next value, or raise StopIteration¶
-
send
(arg) → send 'arg' into generator,¶ return next yielded value or raise StopIteration.
-
throw
(typ[, val[, tb]]) → raise exception in generator,¶ return next yielded value or raise StopIteration.
-
chainlet.genlink.
genlet
(generator_function=None, prime=True)¶ Decorator to convert a generator function to a
ChainLink
Parameters: - generator_function (generator) – the generator function to convert
- prime (bool) – advance the generator to the next/first yield
When used as a decorator, this function can also be called with and without keywords.
@genlet def pingpong(): "Chainlet that passes on its value" last = yield while True: last = yield last @genlet(prime=True) def produce(): "Chainlet that produces a value" while True: yield time.time() @genlet(True) def read(iterable): "Chainlet that reads from an iterable" for item in iterable: yield item