17

Как вывести сообщение в stderr в Python?

14

Описание проблемы:

Существует несколько способов записи данных в стандартный поток ошибок (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 ответ(ов)

16

Я нашел, что это единственное короткое, гибкое, портативное и читаемое решение:

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 удобно использовать для вывода сообщений об ошибках или другой отладочной информации в поток ошибок, сохраняя при этом удобство и привычный синтаксис.

6

В вашем коде есть ошибка: метод sys.stderr.write() требует аргумент — строку, которую нужно записать в поток ошибок. Правильный вариант будет выглядеть так:

import sys
sys.stderr.write("Ваше сообщение об ошибке\n")

Что касается вашего выбора, да, вы правы, он действительно более читаем и точно передает намерение. Кроме того, это обеспечит совместимость с разными версиями Python.

Редактируя ваш комментарий, могу сказать, что 'питоничность' — это третий аспект, который я рассматриваю после читаемости и производительности. Учитывая эти два критерия, в 80% вашего кода будет "питонично". Списковые включения — это как раз тот элемент, который не всегда используется из-за читаемости, но при этом очень мощный инструмент в Python.

4

Конечно! Вот перевод в стиле ответа на 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.

1

В Python 2 я бы выбрал следующий способ записи в стандартный поток ошибок:

print >> sys.stderr, 'spam'

Этот метод удобен тем, что вы можете просто выводить списки, словари и т.д. без необходимости преобразования их в строку:

print >> sys.stderr, {'spam': 'spam'}

Вместо этого вам пришлось бы использовать более громоздкий способ:

sys.stderr.write(str({'spam': 'spam'}))

Используя print, вы получаете более лаконичный и читаемый код.

0

Я бы сказал, что ваш первый подход:

print >> sys.stderr, 'spam'

является «Единственным... очевидным способом сделать это». Остальные варианты не соответствуют правилу №1 («Красивое лучше, чем уродливое»).

-- Правка для 2020 года --

Выше был мой ответ для Python 2.7 в 2011 году. Теперь, когда Python 3 является стандартом, я считаю «правильным» ответом:

print("spam", file=sys.stderr)
Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь