Я использую Python ftplib
для написания небольшого FTP-клиента, но некоторые функции в пакете не возвращают вывод строки, а печатают в stdout
. Я хочу перенаправить stdout
на объект, с которого я смогу прочитать вывод.
Я знаю, stdout
может быть перенаправлен в любой обычный файл с:
stdout = open("file", "a")
Но я предпочитаю метод, который не использует локальный диск.
Я ищу что-то похожее на BufferedReader
Java, которое можно использовать для переноса буфера в поток.
stdout = open("file", "a")
, что само по себе что-либо перенаправит.Ответы:
источник
stdout
объект, так как он всегда доступен вsys.__stdout__
. См. Docs.python.org/library/sys.html#sys.__stdout__ .finally:
блоке, поэтому он также переназначается, если между ними возникает исключение.try: bkp = sys.stdout ... ... finally: sys.stdout = bkp
В Python 3.4 есть функция contextlib.redirect_stdout () :
Вот пример кода, который показывает, как реализовать его на старых версиях Python .
источник
redirect_stderr
на последнем Python тоже!Просто добавьте к ответу Неда выше: вы можете использовать это для перенаправления вывода на любой объект, который реализует метод write (str) .
Это может быть использовано для "ловли" вывода stdout в приложении с графическим интерфейсом.
Вот глупый пример в PyQt:
источник
Начиная с Python 2.6 вы можете использовать в качестве замены все, что реализует
TextIOBase
API из модуля io. Это решение также позволяет вам использоватьsys.stdout.buffer.write()
в Python 3 запись (уже) закодированных байтовых строк в стандартный вывод (см. Стандартный вывод в Python 3 ). ИспользованиеStringIO
не будет работать, потому чтоsys.stdout.encoding
ниsys.stdout.buffer
будет доступно.Решение с использованием TextIOWrapper:
Это решение работает для Python 2> = 2.6 и Python 3.
Обратите внимание, что наш новый
sys.stdout.write()
принимает только строки Unicode иsys.stdout.buffer.write()
принимает только строки байтов. Это может не относиться к старому коду, но часто это относится к коду, который создан для запуска на Python 2 и 3 без изменений, что опять-таки часто используетсяsys.stdout.buffer
.Вы можете создать небольшой вариант, который принимает Unicode и байтовые строки для
write()
:Вам не нужно устанавливать кодировку буфера sys.stdout.encoding, но это помогает при использовании этого метода для тестирования / сравнения вывода скрипта.
источник
Этот метод восстанавливает sys.stdout, даже если есть исключение. Он также получает любой вывод до исключения.
Протестировано в Python 2.7.10 с использованием
io.BytesIO()
Протестировано в Python 3.6.4 с использованием
io.StringIO()
Боб, добавил для случая, если вы чувствуете, что что-то из эксперимента с измененным / расширенным кодом может стать интересным в любом смысле, в противном случае вы можете удалить его
источник
Контекстный менеджер для python3:
используйте как это:
источник
В Python3.6, то
StringIO
иcStringIO
модули ушли, вы должны использоватьio.StringIO
instead.So вы должны сделать это как первый ответ:источник
Используйте
pipe()
и напишите в соответствующий дескриптор файла.https://docs.python.org/library/os.html#file-descriptor-operations
источник
Вот еще один взгляд на это.
contextlib.redirect_stdout
с тем,io.StringIO()
что задокументировано , отлично, но все же немного многословно для повседневного использования. Вот как сделать его однострочным путем создания подклассовcontextlib.redirect_stdout
:Поскольку __enter__ возвращает self, у вас есть объект менеджера контекста, доступный после выхода из блока with. Более того, благодаря методу __repr__ строковое представление объекта менеджера контекста фактически является stdout. Итак, теперь у вас есть,
источник