Что делает этот фрагмент кода c `sys.stdin`?

496 просмотра
0
0 Комментариев

import sys
save_stdin=sys.stdin
sys.stdin=open("in/63.in")
#
#
sys.stdin = save_stdin


Добавить комментарий

2 Answers

Python Опубликовано 14.12.2018
0

Это достаточно популярный в олимпиадном программировании (на это наталкивает in в пути и незакрытие файла) способ организации быстрого переключения (в исходном коде) ввода/вывода между стандартными потоками (известными, как stdin и stdout) и файлами.

Решение пишется с использованием stdin.

  • Когда необходим ввод из файла, эти строчки нужно раскомментировать.
  • Когда нужен сам stdin, их нужно закомментировать.

На практике, если выйти за рамки решения задачек и посмотреть на разработку программного обеспечения, так лучше не делать, поскольку стандартный поток может быть определён из оболочки (shell) ОС при запуске, без изменений в программе и файловой системе. Это более гибкий подход.

Такие строчки имеют смысл только в том случае, если система проверки задачи требует ввода и вывода из конкретных файлов. Во всех остальных случаях stdin удобнее:

  • Если не направить потоки ввода из/в файлы, то при запуске программы будет интерактивная сессия, где можно ввести данные с клавиатуры.
  • Если нужно проверить сразу несколько наборов входных данных, можно написать скриптик для оболочки (*.bat, *.sh, *.bash), который сам всё подставит на место stdin и stdout без необходимости менять программу.
Добавить комментарий
0

Код в вопросе временно перенаправляет стандартный ввод Питона из файла (sys.stdin = save_stdin восстанавливает старое значение).

Намерение кода эмулировать оператор < в командной строке (shell):

$ python ваш-скрипт.py < in/63.in

Ввод (input(), for line in sys.stdin, etc) читается из 63.in файла, расположенного в дочерней (относительно текущей рабочей директории) in директории.

Присваивание sys.stdin не работает, если ввод читается на более низком уровне, например, когда Питон скрипт запускает дочерний процесс, который что-то читает из стандартного ввода (вот пример кода, который показывает как перенаправить вывод (stdout) на уровне file descriptors, чтобы поддерживать и внешние процессы, C расширения и другой Питон код, который не пользуется высокоуровневым интерфейсом). Подобные вещи могут к неожиданным багам приводить (например, связанным с кэшом ввода), поэтому если есть возможность, то следует командную строчку изменить и не перенаправлять sys.stdin на уровне Питона.

Добавить комментарий
Напишите свой ответ на данный вопрос.
Scroll Up