Pregunta ¿Cómo imprimir en stderr en Python 2?


He encontrado al menos tres formas de imprimir en stderr:

 import sys

 print >> sys.stderr, 'spam'

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

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

Parece contradecir zen de Python # 13  , entonces, ¿cuál es la forma preferida de hacerlo? ¿Hay ventajas o desventajas de una manera u otra?

  Debería haber una, y preferiblemente solo una, forma obvia de hacerlo.


988
2018-04-07 00:59


origen


Respuestas:


Encontré este es el único corto + flexible + portátil + legible:

from __future__ import print_function
import sys

def eprint(*args, **kwargs):
    print(*args, file=sys.stderr, **kwargs)

La función eprint se puede usar de la misma manera que el estándar print función:

>>> print("Test")
Test
>>> eprint("Test")
Test
>>> eprint("foo", "bar", "baz", sep="---")
foo---bar---baz

845
2018-02-20 13:31



sys.stderr.write() es mi elección, solo más legible y diciendo exactamente lo que pretendes hacer y portátil en todas las versiones.

Editar: ser 'pitónico' es un tercer pensamiento para mí sobre la legibilidad y el rendimiento ... con estas dos cosas en mente, con python, el 80% de tu código será pitónico. la comprensión de la lista es la "gran cosa" que no se utiliza con tanta frecuencia (legibilidad).


399
2018-04-07 01:03



por Python 2 mi elección es: print >> sys.stderr, 'spam' Porque simplemente puede imprimir listas / dictados, etc. sin convertirlo a cadena. print >> sys.stderr, {'spam': 'spam'} en lugar de: sys.stderr.write(str({'spam': 'spam'}))


120
2017-11-08 17:29



print >> sys.stderr se ha ido en Python3. http://docs.python.org/3.0/whatsnew/3.0.html dice:

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

Desafortunadamente, esto es bastante feo. Alternativamente, use

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

pero ten en cuenta que write no es un reemplazo 1: 1 para print.


97
2018-04-04 10:00



Nadie es mencionado logging aún, pero el registro se creó específicamente para comunicar mensajes de error. Por defecto está configurado para escribir en stderr. Este script:

# foo.py
import logging
logging.basicConfig(format='%(message)s')

logging.warn('I print to stderr by default')
logging.info('For this you must change the level and add a handler.')
print('hello world')

tiene el siguiente resultado cuando se ejecuta en la línea de comando:

$ python3 foo.py > bar.txt
I print to stderr by default

(y bar.txt contiene el 'hola mundo')


52
2017-12-23 16:04



Yo diría que tu primer acercamiento:

print >> sys.stderr, 'spam' 

es el . . . obvio forma de hacerlo "Los otros no cumplen con la regla n. ° 1 (" Hermosa es mejor que fea ").


32
2018-04-07 01:05



Hice lo siguiente con Python 3:

from sys import stderr

def print_err(*args, **kwargs):
    print(*args, file=stderr, **kwargs)

Así que ahora puedo agregar argumentos de palabra clave, por ejemplo, para evitar el retorno de carro:

print_err("Error: end of the file reached. The word ", end='')
print_err(word, "was not found")

28
2017-12-29 21:40



Esto imitará la función de impresión estándar pero la salida en stderr

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

18
2017-10-06 07:42



EDITAR En retrospectiva, creo que la posible confusión con el cambio de sys.stderr y no ver el comportamiento actualizado hace que esta respuesta no sea tan buena como simplemente usar una función simple como otros han señalado.

Usar parcial solo le ahorra 1 línea de código. La posible confusión no vale la pena de guardar 1 línea de código.

original

Para hacerlo aún más fácil, aquí hay una versión que usa 'parcial', que es una gran ayuda en las funciones de ajuste.

from __future__ import print_function
import sys
from functools import partial

error = partial(print, file=sys.stderr)

Luego lo usa así

error('An error occured!')

Puede verificar que esté imprimiendo en stderr y no en stdout haciendo lo siguiente (código de anulación de http://coreygoldberg.blogspot.com.au/2009/05/python-redirect-or-turn-off-stdout-and.html)

# over-ride stderr to prove that this function works.
class NullDevice():
    def write(self, s):
        pass
sys.stderr = NullDevice()

# we must import print error AFTER we've removed the null device because
# it has been assigned and will not be re-evaluated.
# assume error function is in print_error.py
from print_error import error

# no message should be printed
error("You won't see this error!")

La desventaja de esto es parcial asigna el valor de sys.stderr a la función envuelta en el momento de la creación. Lo que significa, si redirige stderr más tarde, no afectará esta función. Si planeas redirigir stderr, entonces usa el método ** kwargs mencionado por aaguirre en esta página.


16
2017-12-30 02:13



Lo mismo se aplica a stdout:

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

Como se indica en las otras respuestas, impresión ofrece una bonita interfaz que a menudo es más conveniente (por ejemplo, para imprimir información de depuración), mientras escribir es más rápido y también puede ser más conveniente cuando tiene que formatear la salida exactamente de cierta manera. Consideraría la facilidad de mantenimiento también:

  1. Posteriormente, puede decidir cambiar entre stdout / stderr y un archivo normal.

  2. impresión() la sintaxis ha cambiado en Python 3, por lo que si necesita admitir ambas versiones, escribir() podría ser mejor.


6
2017-11-01 11:58