Как распечатать на stderr в Python? - PullRequest
1158 голосов
/ 07 апреля 2011

Существует несколько способов записи в stderr:

 # Note: this first one does not work in Python 3
 print >> sys.stderr, "spam"

 sys.stderr.write("spam\n")

 os.write(2, b"spam\n")

 from __future__ import print_function
 print("spam", file=sys.stderr)

Это, кажется, противоречит дзен Python # 13 , так в чем же разница и есть ли какие-либо преимущества или недостатки в том или ином случае? Какой способ следует использовать?

Должен быть один - и желательно только один - очевидный способ сделать это.

Ответы [ 15 ]

7 голосов
/ 01 ноября 2012

То же самое относится к stdout:

print 'spam'
sys.stdout.write('spam\n')

Как указано в других ответах, print предлагает симпатичный интерфейс, который часто более удобен (например, для печати отладочной информации), в то время как запись быстрее и удобнее, когда необходимо точно отформатировать вывод.Я также рассмотрел бы удобство обслуживания:

  1. Позже вы можете переключиться между stdout / stderr и обычным файлом.

  2. print() Синтаксис изменился в Python 3, поэтому если вам необходимо поддерживать обе версии, write () может быть лучше.

6 голосов
/ 10 февраля 2016

Я работаю в Python 3.4.3.Я вырезал небольшой набор текста, который показывает, как я попал сюда:

[18:19 jsilverman@JSILVERMAN-LT7 pexpect]$ python3
>>> import sys
>>> print("testing", file=sys.stderr)
testing
>>>
[18:19 jsilverman@JSILVERMAN-LT7 pexpect]$ 

Это сработало?Попробуйте перенаправить stderr в файл и посмотрите, что произойдет:

[18:22 jsilverman@JSILVERMAN-LT7 pexpect]$ python3 2> /tmp/test.txt
>>> import sys
>>> print("testing", file=sys.stderr)
>>> [18:22 jsilverman@JSILVERMAN-LT7 pexpect]$
[18:22 jsilverman@JSILVERMAN-LT7 pexpect]$ cat /tmp/test.txt
Python 3.4.3 (default, May  5 2015, 17:58:45)
[GCC 4.9.2] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
testing

[18:22 jsilverman@JSILVERMAN-LT7 pexpect]$

Ну, кроме того факта, что небольшое введение, которое дает вам Python, было добавлено в stderr (куда еще он пойдет?), Это работает.

3 голосов
/ 12 июня 2012

Если вы выполните простой тест:

import time
import sys

def run1(runs):
    x = 0
    cur = time.time()
    while x < runs:
        x += 1
        print >> sys.stderr, 'X'
    elapsed = (time.time()-cur)
    return elapsed

def run2(runs):
    x = 0
    cur = time.time()
    while x < runs:
        x += 1
        sys.stderr.write('X\n')
        sys.stderr.flush()
    elapsed = (time.time()-cur)
    return elapsed

def compare(runs):
    sum1, sum2 = 0, 0
    x = 0
    while x < runs:
        x += 1
        sum1 += run1(runs)
        sum2 += run2(runs)
    return sum1, sum2

if __name__ == '__main__':
    s1, s2 = compare(1000)
    print "Using (print >> sys.stderr, 'X'): %s" %(s1)
    print "Using (sys.stderr.write('X'),sys.stderr.flush()):%s" %(s2)
    print "Ratio: %f" %(float(s1) / float(s2))

Вы обнаружите, что sys.stderr.write () последовательно * в 1004 * 1,81 раз быстрее!

0 голосов
/ 29 мая 2018
import logging
logging.basicConfig(format='[%(levelname)s] %(message)s')

logging.error('is error, alarm!')
logging.warning('is simple waring')

print('hello')

pydoc logging

0 голосов
/ 30 января 2018

Ответ на вопрос: есть разные способы печати stderr в python, но это зависит от 1.) какую версию python мы используем 2.) какой именно вывод мы хотим.

Различие между печатью и функцией записи stderr: stderr : stderr (стандартная ошибка) - это канал, который встроен в каждую систему UNIX / Linux, когда ваша программа аварийно завершает работу и выводит отладочную информацию (например, трассировку вPython), он идет в канал stderr.

print : print - это оболочка, которая форматирует входные данные (input - это пробел между аргументом и новой строкой в ​​конце), а затемвызывает функцию записи для данного объекта, по умолчанию этот объект является sys.stdout, но мы можем передать файл, то есть мы можем также распечатать ввод в файле.

Python2: если мы используем python2, то

>>> import sys
>>> print "hi"
hi
>>> print("hi")
hi
>>> print >> sys.stderr.write("hi")
hi

Завершающая запятая Python2 в Python3 стала параметром, поэтому если мы используем конечные запятые, чтобы избежать перехода на новую строку после печати, это будет в Python3выглядит как print ('Text to print', end = ''), что является синтаксической ошибкой в ​​Python2.

http://python3porting.com/noconv.html

Если мы проверим то же выше сценарийв python3:

>>> import sys
>>> print("hi")
hi

В Python 2.6 имеется импорт future для печати в функцию.Поэтому, чтобы избежать любых синтаксических ошибок и других различий, мы должны начинать любой файл, в котором мы используем print (), с future import print_function.Импорт future работает только в Python 2.6 и более поздних версиях, поэтому для Python 2.5 и более ранних версий у вас есть два варианта.Вы можете преобразовать более сложную печать во что-то более простое или использовать отдельную функцию печати, которая работает как в Python2, так и в Python3.

>>> from __future__ import print_function
>>> 
>>> def printex(*args, **kwargs):
...     print(*args, file=sys.stderr, **kwargs)
... 
>>> printex("hii")
hii
>>>

Случай: Отметьте, чтоsys.stderr.write () или sys.stdout.write () (stdout (стандартный вывод) - это канал, который встроен в каждую систему UNIX / Linux) не является заменой для печати, но да, мы можем использовать его как альтернативув некоторых случаях.Print - это оболочка, которая оборачивает ввод пробелом и символом новой строки в конце и использует функцию записи для записи.По этой причине sys.stderr.write () работает быстрее.

Примечание: мы также можем отслеживать и отлаживать, используя Logging

#test.py
import logging
logging.info('This is the existing protocol.')
FORMAT = "%(asctime)-15s %(clientip)s %(user)-8s %(message)s"
logging.basicConfig(format=FORMAT)
d = {'clientip': '192.168.0.1', 'user': 'fbloggs'}
logging.warning("Protocol problem: %s", "connection reset", extra=d)

https://docs.python.org/2/library/logging.html#logger-objects

...