从python中的多个线程捕获打印输出

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (1)
  • 关注 (0)
  • 查看 (406)

我有一个函数,内部lauches并行运行多个线程。线程打印的东西,我想从外部函数捕获此输出。我尝试了下一个代码来捕获输出:

import sys, io
stdout = sys.stdout
sys.stdout = io.StringIO()
threads_conn(connect, devices) #- here many threads starts with many print inside
output = sys.stdout.getvalue()
sys.stdout = stdout

print(output)

这段代码有效。但问题是只有当所有的元素都完成时才会打印输出。所以我冻结了。完成所有线程后 - 打印整个输出。我想拥有的东西 - 一旦它在内部生成就有输出 - 换句话说就是实时输出。现在我立刻打印出整个输出缓冲区。 如何实时输出所有线程?

提问于
用户回答回答于

你想要做的就是编写自己的TextIOBase类(或者,如果你想要二进制数据,编写自己的数据,RawIOBase然后TextIOWrapper在它周围包装一个股票),你可以在那里放置你想要的任何行为。

正如您从文档中看到的那样。所有你需要实现TextIOBasedetachreadreadline,和write。前三个与你正在做的事情无关。

那么,你应该write怎么样?嗯,这取决于你想做什么。

听起来你的目标是将所有东西都发送给真正的stdout和a StringIO。如果是这样,这是非常微不足道的。

唯一的问题是,如果其中一个目标引发异常,或者写的字节少于另一个,那么你想要做什么等等。因为一个IOString永远不会做任何一个,我们可以写一些非常愚蠢的东西,只是假设无论如何真正的stdout做的是正确的事情。

class TeeTextIO(io.TextIOBase):
    def __init__(self, target):
        self.target = target
        self.stringio = io.StringIO()
    def write(self, s):
        writecount = self.target.write(s)
        self.stringio.write(s[:writecount])
        return writecount

现在:

stdout = sys.stdout
sys.stdout = TeeTextIO(sys.stdout)
threads_conn(connect, devices) #- here many threads starts with many print inside
output = sys.stdout.stringio.getvalue()
sys.stdout = stdout

现在,输出已经变为现实stdout,但它也被存储在StringIO以后你想做的任何事情中。

(请注意,这个类可以使用任何 TextIOBase文件,比如文件open,而不仅仅是文件stdout。它没有花费任何东西使它变得通用,为什么不呢?)

如果你想做一些完全不同的事情,比如write在10个不同的文件中随机传播,怎么办?应该很明显:

class SpreadTextWriter(io.TextIOBase):
    def __init__(self, *files):
        self.files = files
    def write(self, s):
        return random.choice(self.files).write(s)

扫码关注云+社区

领取腾讯云代金券