我有一个 python 生成器,它产生文件的一部分(一个 wsgi app_iter
),我需要将它传递给一个期望它具有经典read
和readlines
方法的接口(我想将它作为wsgi.input
另一个传递Request
)。
是否有可能以一种不会将整个生成器内容具体化到内存中的方式来做到这一点?这个想法是将生成器包装在具有read
and readline
(例如BytesIO
or StringIO
)的东西中,并以懒惰的方式进行。
这当然是可能的。这是一段效率极低的代码,可以为您提供这个想法:
class ReadWrapper:
def __init__(self, app_iter):
self.iterator = iter(app_iter)
self.buffer = ''
def readline(self):
while '\n' not in self.buffer:
try:
self.buffer += next(self.iterator)
except StopIteration:
result = self.buffer
self.buffer = ''
return result
idx = self.buffer.find('\n')
result = self.buffer[:idx+1]
self.buffer = self.buffer[idx+1:]
return result
read()
将是相似的,除了\n
你正在寻找指定的字节数(如果没有指定大小,则寻找迭代器的结尾)而不是寻找。
上述代码的可悲的低效率在于它的处理方式self.buffer
:你真的不想\n
在每一步都搜索整个事情,或者做这么多潜在的大副本。