使用greenlet嵌套生成器
greengen的Python项目详细描述
格林根
greengen是一个python包,它允许实现生成器,而不必一直生成项。 相反,任何从greengen生成器调用的内部函数都可以直接向外部生成器生成项。
安装
pip install greengen
用法
例如,假设我们要实现一个函数,该函数执行一些繁重的业务逻辑,并生成日志。 我们希望在创建日志时立即处理它们。 但是我们的函数必须调用一个很深的helper函数堆栈,然后调用更多的函数, 日志可以写在任何函数中的任何地方。 使用常规生成器实现将非常烦人:
importtimedefdo_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):foriinrange(some_input):logs_and_result=_inner_helper_function(i)# Notice the enormous effort needed in order to retrieve the last result (using StopIteration etc.)whileTrue:try:yieldnext(logs_and_result)# This is a logexceptStopIterationase:result=e.value# This is the resultyieldlog('Result for {} is {}'.format(i,result))breakdef_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):yieldlog('Started calculating')result=2**some_input# (Or whatever other heavy calculation)yieldlog('Finished calculating')returnresult# Will be raised as StopIterationdeflog(stuff):return{'message':str(stuff),'timestamp':time.time()}defmain():forlindo_business_logic_and_yield_logs(42):# Consume the logs however we wantprint('{}: {}'.format(l['timestamp'],l['message']))
使用greengen,此示例可以简化为以下内容:
importtimeimportgreengen@greengen.greengendefdo_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):foriinrange(some_input):# Notice how easy it is to retrieve the result nowresult=_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')returnresultdeflog(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()})defmain():forlindo_business_logic_and_yield_logs(42):# Consume the logs however we wantprint('{}: {}'.format(l['timestamp'],l['message']))
贡献
- 叉开!
- 创建功能分支:
git checkout -b my-new-feature
- 提交更改:
git commit -am 'Add some feature'
- 推到分支:
git push origin my-new-feature
- 提交拉取请求:d
历史记录
TOdo:写入历史记录
学分
待办事项:写学分
许可证
TOdo:写入许可证