python-2.7 Como imprimir em stderr em Python?





7 Answers

import sys
sys.stderr.write()

É a minha escolha, apenas mais legível e dizendo exatamente o que você pretende fazer e portátil em todas as versões.

Edit: sendo 'pythonic' é um terceiro pensamento para mim sobre legibilidade e performance ... com estas duas coisas em mente, com python 80% do seu código será pythonic. compreensão da lista é a "grande coisa" que não é usada com tanta frequência (legibilidade).

python python-2.7 printing stderr zen

Eu me deparei com várias maneiras de escrever para 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)

Parece contradizer o zen do Python # 13 , então qual é a maneira preferida de fazer isso? Existem vantagens ou desvantagens de uma forma ou de outra?

Deve haver uma - e de preferência apenas uma - maneira óbvia de fazê-lo.




print >> sys.stderr se foi em Python3. http://docs.python.org/3.0/whatsnew/3.0.html diz:

Old: print >>sys.stderr, "fatal error"
New: print("fatal error", file=sys.stderr)

Infelizmente, isso é muito feio. Como alternativa, use

sys.stderr.write("fatal error\n")

mas note que write não é uma substituição 1: 1 para print .




Eu diria que sua primeira abordagem:

print >> sys.stderr, 'spam' 

é o "Um ... jeito óbvio de fazê-lo" Os outros não satisfazem a regra # 1 ("Linda é melhor que feia").




Isso imitará a função de impressão padrão, mas a saída no stderr

def print_err(*args):
    sys.stderr.write(' '.join(map(str,args)) + '\n')



O mesmo se aplica ao stdout:

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

Como afirmado nas outras respostas, a impressão oferece uma interface bonita que é geralmente mais conveniente (por exemplo, para imprimir informações de depuração), enquanto a gravação é mais rápida e também pode ser mais conveniente quando você precisa formatar a saída exatamente de uma determinada maneira. Eu consideraria a manutenção também:

  1. Posteriormente, você pode decidir alternar entre stdout / stderr e um arquivo regular.

  2. A sintaxe print () mudou no Python 3, então se você precisar suportar ambas as versões, write () pode ser melhor.




Se você fizer um teste simples:

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))

Você vai descobrir que sys.stderr.write () é consistentemente 1,81 vezes mais rápido!




A resposta para a pergunta é: Há uma maneira diferente de imprimir stderr em python, mas isso depende de 1.) qual versão em python estamos usando 2.) qual saída exata queremos.

A diferença entre a função de gravação de print e stderr: stderr : stderr (erro padrão) é um pipe embutido em todo sistema UNIX / Linux, quando seu programa trava e imprime informações de depuração (como um traceback em Python), ele vai para o stderr tubo.

print : print é um wrapper que formata as entradas (a entrada é o espaço entre o argumento e a nova linha no final) e então chama a função write de um determinado objeto, o objeto dado por padrão é sys.stdout, mas podemos passar um arquivo ou seja, podemos imprimir a entrada em um arquivo também.

Python2: Se estamos usando python2, então

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

A vírgula final do Python2 em Python3 se tornou um parâmetro, portanto, se usarmos vírgulas à direita para evitar a nova linha depois de uma impressão, em Python3 será como imprimir ('Texto para imprimir', fim = ') que é um erro de sintaxe em Python2 .

http://python3porting.com/noconv.html

Se nós verificamos o mesmo acima do sceario em python3:

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

No Python 2.6, há uma importação futura para tornar a impressão em uma função. Portanto, para evitar erros de sintaxe e outras diferenças, devemos iniciar qualquer arquivo em que usarmos print () com a partir da futura print_function de importação. A importação futura funciona somente no Python 2.6 e posterior, portanto, para o Python 2.5 e versões anteriores, você tem duas opções. Você pode converter a impressão mais complexa em algo mais simples ou usar uma função de impressão separada que funcione no Python2 e no Python3.

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

Caso: Apontar para o fato de que sys.stderr.write () ou sys.stdout.write () (stdout (saída padrão) é um canal embutido em cada sistema UNIX / Linux) não é um substituto para impressão, mas sim Podemos usá-lo como uma alternativa em alguns casos. Print é um wrapper que envolve a entrada com espaço e nova linha no final e usa a função write para gravar. Essa é a razão pela qual sys.stderr.write () é mais rápido.

Nota: também podemos rastrear e depurar usando 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




Related