Начиная с Python 3, вы также можете использовать sys.stdout.buffer.write()
для записи (уже) закодированных байтовых строк в стандартный вывод (см. стандартный вывод в Python 3 ).
Когда вы делаете это, простой StringIO
подход не работает, потому что ни sys.stdout.encoding
, ни sys.stdout.buffer
не будут доступны.
Начиная с Python 2.6, вы можете использовать TextIOBase
API , который включает отсутствующие атрибуты:
import sys
from io import TextIOWrapper, BytesIO
# setup the environment
old_stdout = sys.stdout
sys.stdout = TextIOWrapper(BytesIO(), sys.stdout.encoding)
# do some writing (indirectly)
write("blub")
# get output
sys.stdout.seek(0) # jump to the start
out = sys.stdout.read() # read output
# restore stdout
sys.stdout.close()
sys.stdout = old_stdout
# do stuff with the output
print(out.upper())
Это решение работает для Python 2> = 2.6 и Python 3.
Обратите внимание, что sys.stdout.write()
принимает только строки Unicode, а sys.stdout.buffer.write()
принимает только строки байтов.
Это может не относиться к старому коду, но часто это относится к коду, который создан для запуска на Python 2 и 3 без изменений.
Если вам требуется поддержка кода, который напрямую отправляет байтовые строки на стандартный вывод без использования stdout.buffer, вы можете использовать этот вариант:
class StdoutBuffer(TextIOWrapper):
def write(self, string):
try:
return super(StdoutBuffer, self).write(string)
except TypeError:
# redirect encoded byte strings directly to buffer
return super(StdoutBuffer, self).buffer.write(string)
Вам не нужно устанавливать кодировку буфера sys.stdout.encoding, но это помогает при использовании этого метода для тестирования / сравнения выходных данных скрипта.