这对于生成器来说可能是一个很好的用途。它会在产量后准确地从中断的地方恢复,因此减少了您需要的存储量和缓冲区交换(我无法谈论它的性能)。
def getLineGenerator(queue, splitOn):
return_buffer = []
while True:
rcv_data = queue.get(block=True) # We can pull any number of characters here.
for c in rcv_data:
return_buffer.append(c)
if c == splitOn:
yield return_buffer
return_buffer = []
gen = getLineGenerator(myQueue, "\n")
for line in gen:
print line.strip()
编辑:
一旦 JF Sebastian 指出行分隔符可能是多字符,我也必须解决这种情况。我还使用了 jdi 答案中的 StringIO 。我再次无法谈论效率,但我相信它在所有情况下都是正确的(至少是我能想到的那些)。这是未经测试的,因此可能需要一些调整才能实际运行。感谢 JF Sebastian 和 jdi 的回答,最终导致了这个问题。
def getlines(chunks, splitOn="\n"):
r_buffer = StringIO()
for chunk in chunks
r_buffer.write(chunk)
pos = r_buffer.getvalue().find(splitOn) # can't use rfind see the next comment
while pos != -1: # A single chunk may have more than one separator
line = r_buffer.getvalue()[:pos + len(splitOn)]
yield line
rest = r_buffer.getvalue().split(splitOn, 1)[1]
r_buffer.seek(0)
r_buffer.truncate()
r_buffer.write(rest)
pos = rest.find(splitOn) # rest and r_buffer are equivalent at this point. Use rest to avoid an extra call to getvalue
line = r_buffer.getvalue();
r_buffer.close() # just for completeness
yield line # whatever is left over.
for line in getlines(iter(queue.get, None)): # break on queue.put(None)
process(line)