我在Python 3.4中工作,我有一些我不理解的行为:如果我将stdout重定向到一个文件,我能够从子进程中捕获文本。但是,当我重定向到Python文件对象时,我停止捕获该输出。我很想解释(跟随)行为。
我有:
from multiprocessing import Process
def worker():
print('forked output')
def output():
print('redirected')
p = Process(target=worker)
p.daemon = True
p.start()
p.join() # wait for subprocess to terminate
print('end')
Python 3.4中的redirect_stdout
上下文管理器使得stdout变得容易(在这个例子中)。
from contextlib import redirect_stdout
from sys import stdout
from tempfile import TemporaryFile
with TemporaryFile(mode='w+', encoding=stdout.encoding) as buf:
with redirect_stdout(buf):
output() # the function defined above
buf.seek(0)
s = buf.read()
print('output from TemporaryFile:')
print(s)
然后我可以简单地调用脚本来获得以下输出:
$ python stackoverflow.py
output from TemporaryFile:
redirected
forked output
end
这正是我想要的,并且工作正常。
我的困惑源于如果我将TemporaryFile
与TextIOWrapper
切换,我脚本的行为会发生变化。
from io import BytesIO, TextIOWrapper
with TextIOWrapper(BytesIO(), stdout.encoding) as buf:
with redirect_stdout(buf):
output() # the function defined at the start
buf.seek(0)
s = buf.read()
print('output from TextIO:')
print(s)
现在,当我调用程序时,我丢失了分叉进程的输出。
$ python stackoverflow.py
output from TextIO:
redirected
end
发生了什么事?
我怀疑问题与TextIOWrapper
对象没有文件描述符这一事实有关,而os.fork()
(由multiprocessing
使用)可能因此取代了TextIOWrapper
与另一个人TextIOWrapper
,但我承认在那里存在一些混淆(特别是考虑到stdout似乎是fileno()
>>> from sys import stdout
>>> stdout.fileno()
1
>>> stdout
<_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>
已实施。)
<a>
感谢您提供任何信息。
答案 0 :(得分:1)
由于您正在使用多处理,因此应使用该库提供的standard message passing primitives。不要从子进程中调用print()
;这是糟糕的设计。
如果您实际上尝试使用其他人的(非Python)代码,请使用subprocess.check_output()
或其他子进程函数。