Объекты стандартного ввода, вывода и ошибки.
Синтаксис:
import sys
sys.stdin
sys.stdout
sys.stderr
Описание:
sys.stdin
- используется для всех интерактивных входных данных, включая вызовы input()
;sys.stdout
- используется для вывода оператором print()
и выражений, которые возвращают значение, а также для подсказок в функции input()
;sys.stderr
- сообщения об ошибках и собственные запросы переводчика.
Эти потоки являются обычными текстовыми файлами, такими же, как и те, которые возвращаются
функцией open()
.
Их параметры выбираются следующим образом:
В Windows UTF-8 используется для консольного устройства. Не символьные устройства, такие как дисковые файлы и каналы, используют кодировку языкового стандарта системы, то есть кодовую страницу ANSI. Не консольные символьные устройства, такие как NUL
, т.е. где метод isatty()
возвращает True
, используют значение кодовых страниц ввода и вывода консоли при запуске соответственно для sys.stdin
и sys.stdout
/sys.stderr
. По умолчанию используется системная кодировка локали, если процесс изначально не подключен к консоли.
Особое поведение консоли можно изменить, установив переменную окружения PYTHONLEGACYWINDOWSSTDIO
перед запуском Python. В этом случае кодовые страницы консоли используются как для любого другого символьного устройства.
На всех платформах можно переопределить кодировку символов, установив переменную среды PYTHONIOENCODING
перед запуском Python или используя новый параметр командной строки - X utf8 и переменную среды PYTHONUTF8
. Однако для консоли Windows это применимо только в том случае, если также установлено PYTHONLEGACYWINDOWSSTDIO
.
В интерактивном режиме потоки stdout
и stderr
буферизуются по строкам. В противном случае они буферизируются как обычные текстовые файлы. Вы можете переопределить это значение с помощью параметра командной строки -u
.
Примечание. Для записи или чтения
двоичных данных из/в стандартные потоки используйте базовый объект двоичного буфера. Например, чтобы записать
байты в
sys.stdout
используйте
sys.stdout.buffer.write(b'abc')
.
Однако, если вы пишете модуль или библиотеку и не контролируете, в каком контексте будет выполняться ее код, помните, что стандартные потоки могут быть заменены файловыми объектами, такими как
io.StringIO
, которые не поддерживают атрибут буфера.
Изменено в Python 3.9: не интерактивный sys.stderr
теперь буферизуется по строкам, а не полностью.
sys.__stdin__
,
sys.__stdout__
,
sys.__stderr__
:
Эти объекты содержат исходные значения sys.stdin
, sys.stderr
и sys.stdout
. Они используются во время финализации и могут быть полезны для печати в реальном стандартном потоке, независимо от того, был ли перенаправлен объект sys.std*
.
Его также можно использовать для восстановления реальных файлов в известные рабочие файловые объекты, если они были перезаписаны поврежденным объектом. Однако предпочтительный способ сделать это - явно сохранить предыдущий поток перед его заменой и восстановить сохраненный объект.
Примечание. При некоторых условиях
sys.stdin
,
sys.stderr
и
sys.stdout
, а также исходные значения
sys.__stdin__
,
sys.__stdout__
и
sys.__stderr__
могут быть
None
. Обычно это относится к приложениям с графическим интерфейсом Windows, которые не подключены к консоли, а приложения Python запускаются с
pythonw.exe
(1).
Примеры использования sys.stdout
, sys.stderr
:
Сохранение вывода stdout
и/или stderr
в файл.
Этот код ничего не выводит на консоль, но записывает "Hello World" в текстовый файл с именем file.txt
.
stdout = sys.stdout
try:
sys.stdout = open('file.txt', 'w')
print('Hello World')
finally:
# Закрываем file.txt
sys.stdout.close()
sys.stdout = stdout
Чтобы сделать такие вещи менее подверженными ошибкам, Python предоставляет sys.__stdin__
, sys.__stdout__
и sys.__stderr__
которые всегда содержат исходные значения sys.stdin
, sys.stdout
и sys.stderr
. Приведенный выше код можно было бы сделать проще, используя sys.__stdout__
:
try:
sys.stdout = open('file.txt', 'w')
print('blah')
finally:
# Закрываем file.txt
sys.stdout.close()
sys.stdout = sys.__stdout__
Причина, по которой Python имеет как sys.stdout
, так и sys.__stdout__
в основном заключается в удобстве, поэтому вам не нужно создавать переменную для копирования stdout = sys.stdout
Сохранение stdout
и/или stderr
в переменную в Python.
Чтобы сохранить
stdout
в переменную нужно подменить
sys.stdout
собственным объектом
io.StringIO
, сделав что-то вроде:
from io import StringIO
import sys
# сохраняем ссылку, чтобы потом
# снова отобразить вывод в консоли.
tmp_stdout = sys.stdout
# В переменной `result` будет храниться все,
# что отправляется на стандартный вывод
result = StringIO()
sys.stdout = result
# Здесь все, что отправляется на стандартный вывод,
# будет сохранено в переменную `result`.
do_fancy_stuff()
# Снова перенаправляем вывод `sys.stdout` на консоль
sys.stdout = tmp_stdout
# Получаем стандартный вывод как строку!
result_string = result.getvalue()
# далее что-нибудь делаем с переменной стандартного вывода
process_string(result_string)
Перенаправление вывода stdout
и/или stderr
при помощи contextlib.redirect_std*()
.
import contextlib, io
s = io.StringIO()
with contextlib.redirect_stdout(s):
help(pow)
>>> s.getvalue()[:50]
# 'Help on built-in function pow in module builtins:\n'
Чтобы отправить вывод функции help()
в файл на диске, нужно перенаправить вывод в обычный файл:
with open('help.txt', 'w') as fp:
with contextlib.redirect_stdout(fp):
help(pow)
Чтобы отправить вывод help()
в sys.stderr:
import contextlib, sys
with redirect_stdout(sys.stderr):
help(pow)
Пример печати текста в консоль с задержкой.
import sys, time
def teleprint(*args, delay=0.05, str_join=' '):
text = str_join.join(str(x) for x in args)
n = len(text)
for i, char in enumerate(text, 1):
if i == n:
char = f'{char}\n'
sys.stdout.write(char)
sys.stdout.flush()
time.sleep(delay)
# Строка будет печататься с задержкой, как в телетексте...
>>> teleprint('Печать с задержкой!', 10, 12.5, 'Super!!!', delay=0.07)
# Печать с задержкой!, 10, 12.5, Super!!
Сноски
- Если вы не хотите, чтобы при запуске вашей программы открывалось окно терминала, используйте
pythonw.exe
, в противном случае используйте python.exe