我一直在使用下面的代碼片斷沉默(重定向從輸出)叫我的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