是否有一个生成器可以将文本流转换为行流?

时间:2013-07-08 21:54:46

标签: python network-programming generator python-2.4

我正在使用一个网络库,该网络库返回一个生成器,每次Next()调用都会收到任意数量的文本(作为字符串);如果你只是简单地连接每个Next()调用的结果;看起来像标准的英文文本。

每个Next()调用返回的字符串中可能有多个换行符,可能没有。返回的字符串不一定以换行符结尾,即一行文本可以分布在多个Next()调用中。

我试图在第二个库中使用这个数据,需要Next()返回一行文本。绝对关键我不读整个流;这可能是数十亿字节的数据。

是否有内置库来解决此问题?如果没有,有人可以建议编写生成器的最佳方法或另一种解决问题的方法吗?

2 个答案:

答案 0 :(得分:2)

编写一个生成器函数,将块拉下来并将它们分成几行。由于您不知道最后一行是否以换行符结尾,请保存并将其附加到下一个块。

def split_by_lines(text_generator):
    last_line = ""
    try:
        while True:
             chunk = "".join(last_line, next(text_generator))
             chunk_by_line = chunk.split('\n')
             last_line = chunk_by_line.pop()
             for line in chunk_by_line:
                 yield line
    except StopIteration: # the other end of the pipe is empty
        yield last_line
        raise StopIteration

答案 1 :(得分:0)

阅读完编辑后,您可以修改返回任意数量文本的流对象吗?例如,在stream.next()方法中,当调用yields时,流会以某种方式生成字符串并.next()。你能做点什么:

def next(self):
    if '\n' in self.remaining:
        terms = self.remaining.split('\n')
        to_yield, self.remaining = terms[0], ''.join(terms[1:])
        yield to_yield
    else:
        to_yield = self.remaining + self.generate_arbitrary_string()
        while '\n' not in to_yield:
            to_yield += self.generate_arbitrary_string()
        to_yield, self.remaining = terms[0], ''.join(terms[1:])
        yield to_yield        

此伪代码假定流对象使用generate_arbitrary_string()生成一些任意字符串。在您第一次调用next()时,self.remaining字符串应为空,因此您转到else语句。在那里,你连接任意字符串,直到找到newline字符,在第一个newline字符处拆分连接字符串,产生前半部分并将后半部分存储在remaining中。

next()的后续通话中,您首先检查self.remaining是否包含任何newline个字符。如果是这样,产生第一行并存储其余部分。如果没有,请将新的任意字符串附加到self.remaining并继续如上所述。