Python — stdin, stdout и stderr
Прежде чем читать эту статью, давайте разберемся, что такое термины stdin , stdout и stderr .
Стандартный ввод — это дескриптор файла, который пользовательская программа читает, чтобы получить информацию от пользователя. Мы передаем ввод на стандартный ввод (stdin).
Стандартный вывод — программа пользователя записывает обычную информацию в этот дескриптор файла. Вывод возвращается через стандартный вывод (stdout).
Стандартная ошибка — программа пользователя записывает информацию об ошибке в этот дескриптор файла. Ошибки возвращаются через стандартную ошибку (stderr).
Python предоставляет нам файловые объекты, представляющие stdin, stdout и stderr. Давайте посмотрим, как мы могли бы работать с этими объектами, чтобы использовать ввод и вывод программы.
1. sys.stdin
Модуль Python sys предоставляет нам все три файловых объекта для stdin, stdout и stderr. В качестве объекта входного файла мы используем sys.stdin . Это похоже на файл, где вы можете открывать и закрывать его, как и любые другие файлы в Python.
Давайте разберемся на простом примере:
import sys stdin_fileno = sys.stdin # Keeps reading from stdin and quits only if the word 'exit' is there # This loop, by default does not terminate, since stdin is open for line in stdin_fileno: # Remove trailing newline characters using strip() if 'exit' == line.strip(): print('Found exit. Terminating the program') exit(0) else: print('Message from sys.stdin: ---> <> <---'.format(line))
Hi Message from sys.stdin: ---> Hi Hello from AskPythonВыше фрагмент кода продолжает чтение входных данных из stdin и выводит сообщение на консоли ( stdout ) до тех пор , слово exit не встречаются.
Примечание. Обычно мы не закрываем объект файла stdin по умолчанию, хотя это разрешено. Итак, stdin_fileno.close() — допустимый код Python.
Теперь, когда мы немного знаем о stdin , перейдем к stdout .
2. sys.stdout
В качестве объекта выходного файла мы используем sys.stdout . Он похож на sys.stdin , но напрямую отображает все, что написано в нем, в консоли.
В приведенном ниже фрагменте показано, что мы получаем вывод в консоль, если пишем в sys.stdout .
import sys stdout_fileno = sys.stdout sample_input = ['Hi', 'Hello from AskPython', 'exit'] for ip in sample_input: # Prints to stdout stdout_fileno.write(ip + '\n')Hi Hello from AskPython exit3. sys.stderr
Это похоже на sys.stdout потому что он также sys.stdout непосредственно выводит в консоль. Но разница в том, что он печатает только сообщения об исключениях и ошибках. (Вот почему он называется стандартной ошибкой).
Проиллюстрируем это на примере.
import sys stdout_fileno = sys.stdout stderr_fileno = sys.stderr sample_input = ['Hi', 'Hello from AskPython', 'exit'] for ip in sample_input: # Prints to stdout stdout_fileno.write(ip + '\n') # Tries to add an Integer with string. Raises an exception try: ip = ip + 100 # Catch all exceptions except: stderr_fileno.write('Exception Occurred!\n')Hi Exception Occurred! Hello from AskPython Exception Occurred! exit Exception Occurred!Как вы можете заметить, для всех входных строк мы пытаемся добавить к Integer, что вызовет исключение. Мы перехватываем все такие исключения и печатаем еще одно сообщение отладки с помощью sys.stderr .
Перенаправление в файл
Мы можем перенаправить дескрипторы файлов stdin , stdout и stderr в любой другой файл (дескриптор файла). Это может быть полезно, если вы хотите регистрировать события в файле без использования какого-либо другого модуля, такого как Logging.
Приведенный ниже фрагмент перенаправляет вывод ( stdout ) в файл с именем Output.txt .
Итак, мы не увидим ничего, напечатанного в консоли, потому что теперь это печатается в самом файле! В этом суть перенаправления вывода. Вы «перенаправляете» вывод в другое место. (На этот раз в Output.txt , а не в консоль)
import sys # Save the current stdout so that we can revert sys.stdou after we complete # our redirection stdout_fileno = sys.stdout sample_input = ['Hi', 'Hello from AskPython', 'exit'] # Redirect sys.stdout to the file sys.stdout = open('Output.txt', 'w') for ip in sample_input: # Prints to the redirected stdout (Output.txt) sys.stdout.write(ip + '\n') # Prints to the actual saved stdout handler stdout_fileno.write(ip + '\n') # Close the file sys.stdout.close() # Restore sys.stdout to our old saved file handler sys.stdout = stdout_filenoroot@ubuntu:~# python3 output_redirection.py Hi Hello from AskPython exit root@ubuntu:~# cat Output.txt Hi Hello from AskPython exitКак видите, мы распечатали вывод как в консоль, так и в Output.txt .
Сначала мы сохраняем исходный sys.stdout обработчик файла sys.stdout в другую переменную. Нам это нужно не только для восстановления sys.stdout в старом обработчике (указывающем на консоль), но мы также можем печатать на консоль, используя эту переменную!
Обратите внимание, что после записи в файл мы закрываем его, аналогично тому, как мы закрываем файл, потому что этот файл все еще был открыт.
Наконец, мы восстанавливаем обработчик sys.stdout в консоли, используя переменную stdout_fileno .
Аналогичный процесс можно выполнить для перенаправления ввода и ошибок, заменив sys.stdout на sys.stdin или sys.stderr и работая с sys.stderr и исключениями вместо вывода.