我一直在使用下面的代码片断沉默(重定向从输出)叫我的Python脚本的C代码:的Python 3:无缓冲VS缓冲流
from ctypes import CDLL, c_void_p
import os
import sys
# Code
class silence(object):
def __init__(self, stdout=os.devnull):
self.outfile = stdout
def __enter__(self):
# Flush
sys.__stdout__.flush()
# Save
self.saved_stream = sys.stdout
self.fd = sys.stdout.fileno()
self.saved_fd = os.dup(self.fd)
# Open the redirect
self.new_stream = open(self.outfile, 'wb', 0)
self.new_fd = self.new_stream.fileno()
# Replace
os.dup2(self.new_fd, self.fd)
def __exit__(self, *args):
# Flush
self.saved_stream.flush()
# Restore
os.dup2(self.saved_fd, self.fd)
sys.stdout = self.saved_stream
# Clean up
self.new_stream.close()
os.close(self.saved_fd)
# Test case
libc = CDLL('libc.so.6')
# Silence!
with silence():
libc.printf(b'Hello from C in silence\n')
的想法是重定向与stdout
和相关的FD将其替换为与打开的空设备关联的一个。与无缓冲输出
$ python2.7 test.py
$ python3.3 -u test.py
$ python3.3 test.py
Hello from C in silence
下的Python 2.7和3.3这确实工作:不幸的是,它没有的Python 3下正常工作。不过,我不确定其根本原因。即使stdout
被缓冲,对sys.saved_stream.flush()
的调用最终应在C级调用fflush(stdout)
(将输出清空到空设备)。
我误解了Python 3 I/O模型的哪一部分?
尝试['与stdout_redirected():'](http://stackoverflow.com/a/22434262/4279) – jfs 2015-01-27 08:31:50
redirect_stdout没有帮助,如果写入标准输出来自C库代码(如printf和朋友)。 – 2015-01-27 11:35:38
阅读完整答案(注意函数名称) – jfs 2015-01-27 11:37:03