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

时间:2018-07-25 21:13:58

标签: python multithreading output capture

我有一个函数,可以在内部启动并行运行的多个线程。线程会打印一些内容,我想从外部函数捕获此输出。我尝试下一个代码来捕获输出:

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)

此代码有效。但是问题是仅在所有广告完成后才输出输出。所以我冻结了。完成所有线程后,将输出整个输出。我想要的-在内部生成后立即输出-换句话说,是实时的。现在,我可以一次打印出整个缓冲区。 如何使所有线程实时输出?

1 个答案:

答案 0 :(得分:1)

您想要做的是编写自己的TextIOBase类(或者,如果您想要二进制数据,则编写自己的RawIOBase,然后在其周围包裹股票TextIOWrapper),其中您可以随心所欲地进行行为。

the docs中可以看到。您只需为TextIOBasedetachreadreadline实现write。而且前三个与您的工作无关。


那么,您的write应该是什么样?好吧,这取决于您要做什么。

听起来您的目标是使所有内容同时进入实际标准输出和StringIO。如果是这样,这是非常琐碎的。

唯一的问题是,如果其中一个目标引发异常,或者比另一个目标写入更少的字节,等等。既然IOString永远不会做任何一个,我们可以写真的很愚蠢,只是假设真正的标准配置所做的是正确的事情。

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中,以备日后使用。

(请注意,该类将与 any 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)