我有一个函数,可以在内部启动并行运行的多个线程。线程会打印一些内容,我想从外部函数捕获此输出。我尝试下一个代码来捕获输出:
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)
此代码有效。但是问题是仅在所有广告完成后才输出输出。所以我冻结了。完成所有线程后,将输出整个输出。我想要的-在内部生成后立即输出-换句话说,是实时的。现在,我可以一次打印出整个缓冲区。 如何使所有线程实时输出?
答案 0 :(得分:1)
您想要做的是编写自己的TextIOBase
类(或者,如果您想要二进制数据,则编写自己的RawIOBase
,然后在其周围包裹股票TextIOWrapper
),其中您可以随心所欲地进行行为。
从the docs中可以看到。您只需为TextIOBase
,detach
,read
和readline
实现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)