Подавить печать stdout/stderr из функций PythonPython

Программы на Python
Ответить
Anonymous
 Подавить печать stdout/stderr из функций Python

Сообщение Anonymous »

У меня есть скрипт Python, который использует некоторые закрытые функции Python (т. е. я не могу редактировать эти функции), предоставленные моим работодателем. Когда я вызываю эти функции, они выводят на мой Linux-терминал вывод, который я хотел бы подавить. Я пробовал перенаправить stdout/stderr через;

Код: Выделить всё

orig_out = sys.stdout
sys.stdout = StringIO()
rogue_function()
sys.stdout = orig_out
но это не позволяет перехватить вывод. Я думаю, что функции, которые я вызываю через Python (rogue_function() сверху), на самом деле являются оболочками для скомпилированного C-кода, которые на самом деле выполняют печать.
Кто-нибудь знает, как я могу выполнить «глубокий захват» любого вывода, переданного в stdout/stderr функцией (и любых подфункций, которые вызывает функция)?
UPDATE:
В итоге я воспользовался методом, описанным в выбранном ответе ниже, и написал диспетчер контекста для подавления stdout и stderr:

Код: Выделить всё

import os

# 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()
Это работает «очень хорошо». Он подавляет распечатку мошеннических функций, которые загромождали мой сценарий. При тестировании я заметил, что он допускает возникновение исключений, а также некоторую печать журнала, и мне не совсем понятно, почему. Я думаю, это как-то связано с тем, когда эти сообщения отправляются на стандартный вывод / stderr (я думаю, это происходит после выхода из моего контекстного менеджера). Если кто-нибудь может это подтвердить, мне было бы интересно услышать подробности...

Подробнее здесь: https://stackoverflow.com/questions/111 ... -functions
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»