Как вывести сообщение в stderr в Python?
Описание проблемы:
Существует несколько способов записи данных в стандартный поток ошибок (stderr) в Python. Я нашёл следующие методы:
print >> sys.stderr, "spam" # Только для Python 2.
sys.stderr.write("spam\n")
os.write(2, b"spam\n")
from __future__ import print_function
print("spam", file=sys.stderr)
Мне интересно, каковы различия между этими методами? Какой из них следует предпочесть в современных приложениях?
5 ответ(ов)
Я нашел, что это единственное короткое, гибкое, портативное и читаемое решение:
import sys
def eprint(*args, **kwargs):
print(*args, file=sys.stderr, **kwargs)
Этот необязательный метод eprint
позволяет избежать повторений. Его можно использовать так же, как и стандартную функцию print
:
>>> print("Тест")
Тест
>>> eprint("Тест")
Тест
>>> eprint("foo", "bar", "baz", sep="---")
foo---bar---baz
Таким образом, eprint
удобно использовать для вывода сообщений об ошибках или другой отладочной информации в поток ошибок, сохраняя при этом удобство и привычный синтаксис.
В вашем коде есть ошибка: метод sys.stderr.write()
требует аргумент — строку, которую нужно записать в поток ошибок. Правильный вариант будет выглядеть так:
import sys
sys.stderr.write("Ваше сообщение об ошибке\n")
Что касается вашего выбора, да, вы правы, он действительно более читаем и точно передает намерение. Кроме того, это обеспечит совместимость с разными версиями Python.
Редактируя ваш комментарий, могу сказать, что 'питоничность' — это третий аспект, который я рассматриваю после читаемости и производительности. Учитывая эти два критерия, в 80% вашего кода будет "питонично". Списковые включения — это как раз тот элемент, который не всегда используется из-за читаемости, но при этом очень мощный инструмент в Python.
Конечно! Вот перевод в стиле ответа на StackOverflow:
print("fatal error", file=sys.stderr)
Python 2:
print >> sys.stderr, "fatal error"
Подробный ответ
В Python 3 конструкция print >> sys.stderr
была удалена. Документация Python 3.0 гласит:
Старый способ:
print >> sys.stderr, "fatal error"
Новый способ:
print("fatal error", file=sys.stderr)
Для многих из нас может показаться несколько неестественным перемещать указание целевого потока в конец команды. Альтернативный способ:
sys.stderr.write("fatal error\n")
выглядит более ориентированным на объектный подход и элегантно переходит от общего к частному. Однако стоит отметить, что метод write
не является 1:1 заменой для print
.
В Python 2 я бы выбрал следующий способ записи в стандартный поток ошибок:
print >> sys.stderr, 'spam'
Этот метод удобен тем, что вы можете просто выводить списки, словари и т.д. без необходимости преобразования их в строку:
print >> sys.stderr, {'spam': 'spam'}
Вместо этого вам пришлось бы использовать более громоздкий способ:
sys.stderr.write(str({'spam': 'spam'}))
Используя print
, вы получаете более лаконичный и читаемый код.
Я бы сказал, что ваш первый подход:
print >> sys.stderr, 'spam'
является «Единственным... очевидным способом сделать это». Остальные варианты не соответствуют правилу №1 («Красивое лучше, чем уродливое»).
-- Правка для 2020 года --
Выше был мой ответ для Python 2.7 в 2011 году. Теперь, когда Python 3 является стандартом, я считаю «правильным» ответом:
print("spam", file=sys.stderr)
Почему используется string.join(list), а не list.join(string)?
Создание словаря с помощью генератора словарей
Как получить полный путь к директории текущего файла?
UnicodeDecodeError: Кодек 'charmap' не может декодировать байт X в позиции Y: символ отображается как <неопределённый>
Найти все файлы с расширением .txt в директории на Python