我有一個Python腳本正在使用我的僱主提供的一些封閉的Python函數(即我無法編輯這些函數)。當我調用這些函數時,它們將打印輸出到我想禁止的linux終端。我試過重定向stdout/stderr;從Python函數中抑制stdout/stderr打印
orig_out = sys.stdout
sys.stdout = StringIO()
rogue_function()
sys.stdout = orig_out
但這無法捕捉輸出。我認爲我通過Python調用的函數(來自上面的rogue_function())真的是編譯C代碼的包裝器,它們實際上正在進行打印。
有沒有人知道我可以通過函數(以及函數調用的任何子函數)對stdout/stderr進行任何打印的「深度捕獲」?
UPDATE:
我最終採取如下選擇的答案中概述的方法和寫作上下文管理器來剿輸出和錯誤:
# Define a context manager to suppress stdout and stderr.
class suppress_stdout_stderr(object):
'''
A context manager for doing a "deep suppression" of stdout and stderr in
Python, i.e. will suppress all print, even if the print originates in a
compiled C/Fortran sub-function.
This will not suppress raised exceptions, since exceptions are printed
to stderr just before a script exits, and after the context manager has
exited (at least, I think that is why it lets exceptions through).
'''
def __init__(self):
# Open a pair of null files
self.null_fds = [os.open(os.devnull,os.O_RDWR) for x in range(2)]
# Save the actual stdout (1) and stderr (2) file descriptors.
self.save_fds = [os.dup(1), os.dup(2)]
def __enter__(self):
# Assign the null pointers to stdout and stderr.
os.dup2(self.null_fds[0],1)
os.dup2(self.null_fds[1],2)
def __exit__(self, *_):
# Re-assign the real stdout/stderr back to (1) and (2)
os.dup2(self.save_fds[0],1)
os.dup2(self.save_fds[1],2)
# Close all file descriptors
for fd in self.null_fds + self.save_fds:
os.close(fd)
要使用這個你剛纔:
with suppress_stdout_stderr():
rogue_function()
這個作品「相當不錯」。它確實抑制了混淆我的腳本的流氓功能的打印輸出。我在測試中注意到它允許通過引發異常以及某些記錄器打印,並且我不完全清楚爲什麼。我認爲這與有關,當這些消息被髮送到stdout/stderr(我認爲它發生在我的上下文管理器退出後)。如果任何人都可以證實這一點,我會很樂意聽取細節...
不[這種方法](http://stackoverflow.com/a/978264/344821)(從相關的側邊欄)工作? – Dougal
而不是設置'sys.stdout'到'StringIO的()',你嘗試將其設置到一個文件?即'sys.stdout的=打開( 'log.txt的', 'W')' – carmenism
杜格爾,謝謝,看起來很有希望,我會嘗試一下明天。我嘗試將它指向一個自定義的NullPointer()類,並且這也不起作用。 – jeremiahbuddha