Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- def pause():
- raw_input('\nPress enter to continue\n')
- def process(content):
- pass
- # Expensive init
- # Work
- # Cleanup
- contents = [object()] * 5
- def simple_example():
- # Init ...
- print '1> Init generator'
- content = yield
- print '1> First content received'
- while content is not None:
- # Work ...
- print '1> Work on content'
- result = process(content)
- content = yield result
- # Cleanup ...
- print '1> Cleanup generator'
- # How to use it ?
- print 'M> Creating an instance of the generator'
- processor = simple_example()
- print 'M> Done'
- print 'M> Booting generator'
- processor.send(None) # Always have to send None to bootstrap
- print 'M> Done'
- for content in contents:
- result = processor.send(content)
- try:
- print 'M> Send end of stream marker'
- processor.send(None) # Send None to finish. Raises StopIteration
- except StopIteration:
- print 'M> Done'
- else:
- print 'M> Failed'
- pause()
- # Verbose, let's use a content manager to do send(None)
- class CoMethod(object):
- def __init__(self, iterator):
- self._iterator = iterator
- def __enter__(self):
- print '-> Enter context manager'
- self._iterator.send(None)
- return self # Could return self.__iterator here
- def __exit__(self, exc_type, exc_val, exc_tb):
- print '-> Exit context manager'
- if exc_type is None:
- try:
- self._iterator.send(None)
- except StopIteration:
- pass
- def __call__(self, value):
- return self._iterator.send(value)
- def __iter__(self):
- # Iterator protocol
- return self._iterator
- # Now we can use it like this:
- with CoMethod(simple_example()) as processor:
- for content in contents:
- processor(content)
- pause()
- # Prettier ?
- # Let's make a decorator
- import functools
- def comethod(func):
- @functools.wraps(func)
- def wrapped(*args, **kwargs):
- return CoMethod(func(*args, **kwargs))
- return wrapped
- # Definition
- @comethod
- def second_example():
- # Init ...
- print '2> Init generator'
- content = yield
- while content is not None:
- # Work ...
- print '2> Work generator'
- result = process(content)
- content = yield result
- # Cleanup ...
- print '2> Clean generator'
- # Now we can use it like this:
- with second_example() as processor:
- for content in contents:
- processor(content)
- pause()
- # Nested
- @comethod
- def counter_example(parent, **options):
- # Init
- print '3> Init counter'
- count = 0
- content = yield
- while content is not None:
- result = parent(content)
- # Work
- print '3> Count'
- count += 1
- content = yield result
- # Cleanup
- print '3> Cleanup, saw', count, 'elements'
- # How to use it
- with second_example() as processor:
- with counter_example(processor) as counter:
- for content in contents:
- counter(content)
- pause()
- # Last helper, a map function on a CoMethod
- CoMethod.map = lambda self, iterable: map(self._iterator.send, iterable)
- # How to use it
- with second_example() as processor:
- with counter_example(processor) as counter:
- counter.map(contents)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement