Вопрос-Ответ

Can I redirect the stdout into some sort of string buffer?

Могу ли я перенаправить стандартный вывод в какой-то строковый буфер?

Я использую python ftplib для написания небольшого FTP-клиента, но некоторые функции в пакете не возвращают строковый вывод, а печатают в stdout. Я хочу перенаправить stdout на объект, из которого я смогу прочитать выходные данные.

Я знаю, stdout может быть перенаправлен в любой обычный файл с:

stdout = open("file", "a")

Но я предпочитаю метод, который не использует локальный диск.

Я ищу что-то вроде BufferedReader в Java, которое можно использовать для преобразования буфера в поток.

Переведено автоматически
Ответ 1
from cStringIO import StringIO # Python3 use: from io import StringIO
import sys

old_stdout = sys.stdout
sys.stdout = mystdout = StringIO()

# blah blah lots of code ...

sys.stdout = old_stdout

# examine mystdout.getvalue()
Ответ 2

В Python 3.4 есть contextlib.redirect_stdout() функция+:

import io
from contextlib import redirect_stdout

with io.StringIO() as buf, redirect_stdout(buf):
print('redirected')
output = buf.getvalue()

Вот пример кода, который показывает, как реализовать это в старых версиях Python.

Ответ 3

Просто добавлю к ответу Неда выше: вы можете использовать это для перенаправления вывода на любой объект, который реализует метод write (str).

Это может быть эффективно использовано для "перехвата" выходных данных стандартного вывода в приложении с графическим интерфейсом.

Вот глупый пример в PyQt:

import sys
from PyQt4 import QtGui

class OutputWindow(QtGui.QPlainTextEdit):
def write(self, txt):
self.appendPlainText(str(txt))

app = QtGui.QApplication(sys.argv)
out = OutputWindow()
sys.stdout=out
out.show()
print "hello world !"
Ответ 4

Контекстный менеджер для python3:

import sys
from io import StringIO


class RedirectedStdout:
def __init__(self):
self._stdout = None
self._string_io = None

def __enter__(self):
self._stdout = sys.stdout
sys.stdout = self._string_io = StringIO()
return self

def __exit__(self, type, value, traceback):
sys.stdout = self._stdout

def __str__(self):
return self._string_io.getvalue()

использовать следующим образом:

>>> with RedirectedStdout() as out:
>>> print('asdf')
>>> s = str(out)
>>> print('bsdf')
>>> print(s, out)
'asdf\n' 'asdf\nbsdf\n'
python