我有一个Python脚本,主要执行两个任务。
multiprocessing.Process(target=...)
我的问题是:有什么方法可以使 "静音"。stdout
而不影响主进程?我曾尝试通过 sys.stdout
但它会影响每一个进程和主进程(程序的每一个实例都指向同一个对象)。
>>> import multiprocessing
>>> import sys
>>> def a():
... print('{} - {}'.format(sys.stdout, id(sys.stdout)))
...
>>> for i in range(5):
... multiprocessing.Process(target=a).start()
...
<_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'> - 140230387621232
<_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'> - 140230387621232
<_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'> - 140230387621232
<_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'> - 140230387621232
>>> <_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'> - 140230387621232
>>> a()
<_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'> - 140230387621232
不可能 删尽 print()
报表 的函数,因为程序的另一个例程在主进程上调用该函数,它需要这些 print 语句。
我还注意到,我可以使用一个布尔标志来指示是否应该执行打印,但我希望有人能给我一个更好的方法。
非常感谢您!我有一个Python脚本,它可以执行打印语句。
我试着通过sys.stdout来改变它,但它会影响每一个进程和主进程(程序的每一个实例都指向同一个对象)
你在这里提供的解决方案实际上是可行的。试着运行这个简单的例子。
def a(no_stdout):
if no_stdout:
sys.stdout = None
print(id(sys.stdout))
multiprocessing.Process(target=a, args=(False,)).start() # Outputs the id
multiprocessing.Process(target=a, args=(True,)).start() # Outputs nothing
在你的例子中,所有的进程都打印出相同的数据,原因是 id
就是 multiprocessing.Process
用途 os.fork
在你的平台上。当分叉时,所有进程的内存都保持相同(甚至在被子进程修改之前都保持在同一个物理地址)。因此,虽然地址相同,但它们各自引用的是不同的 sys.stdout
对象的内存中。
你必须在进程内部进行,在fork之后。这有点粗糙,但似乎是可行的。
#!/usr/bin/env python3
import multiprocessing
import sys
class SinkLogger(object):
def __init__(self):
pass
def write(self, message):
pass
def flush(self):
pass
def a(i):
if (i % 2 == 1):
sys.stdout = SinkLogger()
print('{} - {} - {}'.format(i, sys.stdout, id(sys.stdout)))
for i in range(5):
multiprocessing.Process(target=a, args=(i,)).start()
print("done")
这个想法的来源: 如何用脚本将stdout重定向到文件和控制台?