Nesting generators using greenlets
Project description
Greengen
Greengen is a python package that allows implementing generators without yielding items all the way up. Instead, any inner function called from a greengen generator, can yield items directly to the outer generator.
Installation
pip install greengen
Usage
For example, suppose we want to implement a function that performs some heavy business logic, and generates logs. We want to handle the logs the moment they are created. But our function has to call a deep stack of helper functions, which in their turn call more functions, and logs may be written anywhere inside any function. The implementation with regular generators will be utterly annoying:
import time
def do_business_logic_and_yield_logs(some_input):
yield from _helper_function(some_input)
yield from _more_helper_function(some_input)
def _helper_function(some_input):
for i in range(some_input):
logs_and_result = _inner_helper_function(i)
# Notice the enormous effort needed in order to retrieve the last result (using StopIteration etc.)
while True:
try:
yield next(logs_and_result) # This is a log
except StopIteration as e:
result = e.value # This is the result
yield log('Result for {} is {}'.format(i, result))
break
def _more_helper_function(some_input):
yield from _helper_function(some_input * 100)
yield from _helper_function(some_input ** 2)
def _inner_helper_function(some_input):
yield log('Started calculating')
result = 2 ** some_input # (Or whatever other heavy calculation)
yield log('Finished calculating')
return result # Will be raised as StopIteration
def log(stuff):
return {'message': str(stuff), 'timestamp': time.time()}
def main():
for l in do_business_logic_and_yield_logs(42):
# Consume the logs however we want
print('{}: {}'.format(l['timestamp'], l['message']))
Using Greengen, this example can be simplified into the following:
import time
import greengen
@greengen.greengen
def do_business_logic_and_yield_logs(some_input):
# Notice how we don't need the "yield from" anymore
_helper_function(some_input)
_more_helper_function(some_input)
def _helper_function(some_input):
for i in range(some_input):
# Notice how easy it is to retrieve the result now
result = _inner_helper_function(i)
log('Result for {} is {}'.format(i, result))
def _more_helper_function(some_input):
_helper_function(some_input * 100)
_helper_function(some_input ** 2)
def _inner_helper_function(some_input):
log('Started calculating')
result = 2 ** some_input # (Or whatever other heavy calculation)
log('Finished calculating')
return result
def log(stuff):
# This is the only place in the entire code where we need to be aware of the fact that we are inside a generator.
# This will directly yield the log as the next item in the outer generator ("do_business_logic_and_yield_logs")
greengen.yield_({'message': str(stuff), 'timestamp': time.time()})
def main():
for l in do_business_logic_and_yield_logs(42):
# Consume the logs however we want
print('{}: {}'.format(l['timestamp'], l['message']))
Contributing
- Fork it!
- Create your feature branch:
git checkout -b my-new-feature
- Commit your changes:
git commit -am 'Add some feature'
- Push to the branch:
git push origin my-new-feature
- Submit a pull request :D
History
TODO: Write history
Credits
TODO: Write credits
License
TODO: Write license
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
File details
Details for the file greengen-1.0.1.tar.gz
.
File metadata
- Download URL: greengen-1.0.1.tar.gz
- Upload date:
- Size: 3.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.0.1 requests-toolbelt/0.9.1 tqdm/4.33.0 CPython/3.7.4
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 16568936a550d00025a9fd8bc5c1fc15fe4d29d8e02e37746d28b806c94c4462 |
|
MD5 | ca59a26550cb94d3864f1f0819340218 |
|
BLAKE2b-256 | 5f45919ecfbfc017d385968a457f70ebf1af3043381d950337aa12722e332697 |
File details
Details for the file greengen-1.0.1-py3-none-any.whl
.
File metadata
- Download URL: greengen-1.0.1-py3-none-any.whl
- Upload date:
- Size: 3.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.0.1 requests-toolbelt/0.9.1 tqdm/4.33.0 CPython/3.7.4
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 3551339d45055d59c029bfd3ffdb3ca413d26f00834d07a1bdc3abc1e810a250 |
|
MD5 | b7328b99f9b9315745160ae21bb6f8be |
|
BLAKE2b-256 | 16129d99c7b462c92d24d60115347a46ba3c5afbca67efb0126ae75548d3d3f6 |
File details
Details for the file greengen-1.0.1-py2-none-any.whl
.
File metadata
- Download URL: greengen-1.0.1-py2-none-any.whl
- Upload date:
- Size: 3.8 kB
- Tags: Python 2
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.0.1 requests-toolbelt/0.9.1 tqdm/4.33.0 CPython/3.7.4
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | d65086bb296af0458ba0732dc036d725724383e06dff9c12310e28a8e3e50cc9 |
|
MD5 | eb2da490aa9e77acad0623384ea13fc7 |
|
BLAKE2b-256 | bc4a63887d2337122a5791279fe4003a41288666e91e0660847ce12b6ccc3933 |