我有一项任务,我需要根据某些条件“切换”发电机中间流量的输出。
让我们说我们有一个生成器从某些无限来源产生数据。每次我们从发生器读取1GB数据时,我们都会将输出切换到其他读卡器。
input = MyInfiniteGenerator()
Reader1(input) # does something with the first gigabyte of data
Reader2(input) # does something with the second gigabyte of data
...
当我们将输出从Reader1切换到Reader2时,应该关闭Reader1。我无法改变读者的行为方式,只是迭代输入。
此问题类似于旋转文件日志。
答案 0 :(得分:1)
我建议将您的发电机包装在另一台只能读取您想要的数量的发电机中。 itertools.islice
应该做得很好:
import itertools
gen = someInfiniteGenerator()
while True:
slice = itertools.islice(gen, 1000000) # reads one million items from gen
reader = Reader(slice) # consumes all of the slice
唯一可能出现的问题是,如果gen
永远结束(也就是说,它会引发StopIteration
),除非得到一个空的生成器,否则读取器将会检测到它。如果这是可能性,您可以使用额外级别的生成器来解决它,在生成任何内容之前检查生成器中至少有一个项目:
class EmptyGenerator(Exception):
pass
def notEmptyGen(gen):
try:
first = next(gen)
yield first
except StopIteration: # empty source generator
raise EmptyGenerator()
yield from gen
答案 1 :(得分:0)
您可以执行类似
的操作input_chunk = (i for _, i in zip(xrange(chunk_size), input)) # `range` in Python3
或者,或许更一般地说,
from itertools import takewhile
input_chunk = takewhile(condition, input)
并将input_chunk
提供给Reader1
等
condition
必须是一个带有一个参数的函数 - input
的项目。
另请注意,input
是built-in function的名称,并将其用作变量名称,您将隐藏它。
itertools.takewhile
上的文档。