And*_*ham 7 python stdout python-3.x
我在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')
Run Code Online (Sandbox Code Playgroud)
redirect_stdoutPython 3.4中的上下文管理器使得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)
Run Code Online (Sandbox Code Playgroud)
然后我可以简单地调用脚本来获得以下输出:
$ python stackoverflow.py
output from TemporaryFile:
redirected
forked output
end
Run Code Online (Sandbox Code Playgroud)
这正是我想要的,并且工作正常.
我的困惑来自,如果我,如果我切换事实茎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)
Run Code Online (Sandbox Code Playgroud)
现在,当我调用程序时,我丢失了分叉进程的输出.
$ python stackoverflow.py
output from TextIO:
redirected
end
Run Code Online (Sandbox Code Playgroud)
到底是怎么回事?
我怀疑这个问题与TextIOWrapper对象没有文件描述符这一事实有关,而且os.fork()(由...使用multiprocessing)因此可能会替换TextIOWrapper另一个,但我承认有些混乱(特别是考虑到stdout似乎是TextIOWrapper 已 fileno()实施).
>>> from sys import stdout
>>> stdout.fileno()
1
>>> stdout
<_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>
Run Code Online (Sandbox Code Playgroud)
感谢您提供任何信息.
由于您使用的是多处理,因此您应该使用该库提供的标准消息传递原语。不要print()从子流程中调用;这是糟糕的设计。
如果您实际上尝试使用其他人的(非 Python)代码来实现此功能,请改用subprocess.check_output()或另一个子流程函数。
| 归档时间: |
|
| 查看次数: |
530 次 |
| 最近记录: |