更新:我一直真正想要的是greenlets。
注意:当人们回答并迫使我“提高赌注”时,这个问题发生了一些变化,因为我的琐碎示例进行了琐碎的简化;根据亚历克斯的建议,我不会在这里继续改变它,而是在我头脑更清楚时提出这个问题。
Python 生成器是一件美丽的事情,但我怎样才能轻松地将其分解为模块(结构化编程)?我实际上想要PEP 380,或者至少在语法负担方面具有可比性,但在现有的 Python 中(例如 2.6)
作为一个(当然是愚蠢的)示例,请采取以下措施:
def sillyGenerator():
for i in xrange(10):
yield i*i
for i in xrange(12):
yield i*i
for i in xrange(8):
yield i*i
作为 DRY 的忠实信徒,我在这里发现了重复的模式并将其分解为一种方法:
def quadraticRange(n):
for i in xrange(n)
yield i*i
def sillyGenerator():
quadraticRange(10)
quadraticRange(12)
quadraticRange(8)
...这当然行不通。父级必须在循环中调用新函数,产生结果:
def sillyGenerator():
for i in quadraticRange(10):
yield i
for i in quadraticRange(12):
yield i
for i in quadraticRange(8):
yield i
……比以前还要长!
如果我想将生成器的一部分推送到函数中,我总是需要这个相当冗长的两行包装器来调用它。如果我想支持 send(),情况会变得更糟:
def sillyGeneratorRevisited():
g = subgenerator()
v = None
try:
while True:
v = yield g.send(v)
catch StopIteration:
pass
if v < 4:
# ...
else:
# ...
这还没有考虑到传递异常。每次都是相同的样板!然而,人们不能应用 DRY 并将这个相同的代码分解为一个函数,因为......你需要样板来调用它!我想要的是这样的:
def sillyGenerator():
yield from quadraticRange(10)
yield from quadraticRange(12)
yield from quadraticRange(8)
def sillyGeneratorRevisited():
v = yield from subgenerator()
if v < 4:
# ...
else:
# ...
有没有人可以解决这个问题?我有第一次尝试,但我想知道其他人想出了什么。最终,任何解决方案都必须解决主生成器根据发送到生成器的数据结果执行复杂逻辑的示例,并可能对子生成器进行大量调用:我的用例是用于实现的生成器长时间运行的复杂状态机。