¿Cómo imprimo en stderr en Python?

7 minutos de lectura

avatar de usuario de wim
ingenio

Hay varias formas de escribir en stderr:

print >> sys.stderr, "spam"  # Python 2 only.

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

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

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

¿Cuáles son las diferencias entre estos métodos? ¿Qué método debería preferirse?

  • La primera forma enumerada es una de las muchas cosas eliminadas en Python 3. El consenso parece ser que la sintaxis >> era fea de todos modos, y dado que imprimir ahora es una función, la sintaxis nunca funcionaría.

    –Steve Howard

    5 de agosto de 2011 a las 21:50

  • Yo uso: sys.exit(‘Error: ‘)

    – rígido

    31 de julio de 2013 a las 14:05

  • solo usa imprimir.

    – hombre

    10 dic 2019 a las 19:34

  • @stark sys.exit finaliza el programa; la impresión en stderr no debería.

    – brewmanz

    hace 2 días

  • @hooman no comentes sobre cosas de las que no sabes nada. stdout y stderr escriben en dos flujos de archivos diferentes. El hecho de que sus programas simples usen el mismo dispositivo de salida de terminal para ambos es una coincidencia.

    – brewmanz

    hace 2 días

Avatar de usuario de MarcH
Marcha

Encontré que este es el único corto, flexible, portátil y legible:

# This line only if you still care about Python2
from __future__ import print_function

import sys

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

La función opcional eprint ahorra algo de repetición. Se puede utilizar 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

  • Solo un pensamiento: dado que esto importará la función de impresión, cada otra “impresión” en el script original ahora deberá “funcionalizarse” agregando “(” y “)”. Así que eso es un ligero golpe contra este método, en mi opinión.

    – Dan H.

    12 de noviembre de 2014 a las 18:38


  • @DanH Sí, esto efectivo para que su código esté listo para Python3. ¡Supongo que esta podría ser la razón por la que a muchas personas realmente les gusta!

    – Marcha

    18/11/2014 a las 19:00

  • @MarkH… sí, te obliga a preparar tu código para Python3… también te obliga a hacerlo AHORA, solo para imprimir información de depuración en el stderr… lo que me resultaría más complicado la mayoría de las situaciones cuando intento depurar algo. (¡Preferiría no introducir nuevos errores de sintaxis!) 🙂

    – Dan H.

    20 de noviembre de 2014 a las 14:49

  • FWIW este código no obligarle a utilizar la versión funcional de print en todo su programa. Sólo en el módulo que contiene la definición de eprint(). Póngalo en un archivo pequeño por sí mismo, importe eprint de él a sus otros archivos, y puede continuar usando la declaración print tan largo como tu quieras.

    – alexis

    16 mayo 2017 a las 22:51


  • Además, la conversión de la función de impresión a impresión es un simple reemplazo de búsqueda que 2to3 ya automatiza para usted. Solo hazlo ya si no lo has hecho; python2 desaparecerá en menos de 2 años… Algunas cosas entre 2 y 3 pueden ser un poco complicadas; La función de impresión no es una de ellas. Ver docs.python.org/2/library/2to3.html

    – bobpaul

    16 de mayo de 2018 a las 4:14


Avatar de usuario de Mike Ramírez
Mike Ramírez

import sys
sys.stderr.write()

Es mi elección, simplemente más legible y diciendo exactamente lo que pretende hacer y portátil entre versiones.

Editar: ser ‘pythonic’ es un tercer pensamiento para mí sobre la legibilidad y el rendimiento … con estas dos cosas en mente, con python, el 80% de su código será pythonic. la comprensión de la lista es la “gran cosa” que no se usa con tanta frecuencia (legibilidad).

  • Solo no olvides tirar de la cadena.

    – temoto

    03/04/2012 a las 19:00

  • Ventaja de la print La declaración es fácil de imprimir valores que no son cadenas, sin tener que convertirlos primero. Si necesita una declaración de impresión, le recomendaría usar la tercera opción para estar listo para Python 3

    – vdboor

    6 de abril de 2012 a las 11:22

  • sys.stderr.write() no es nada como print. No agrega una nueva línea.

    – Coronel Pánico

    18 mayo 2012 a las 14:27

  • Esto funciona en Python 2 y 3, lo cual es importante si desea admitir ambos.

    – JonnyJD

    23 de abril de 2013 a las 10:02

  • @SkipHuffman ¿Te refieres a os.linesep. Esto es stderr estamos hablando, después de todo. No quiero que la consola se estropee con la nueva línea incorrecta.

    – jpmc26

    14/07/2015 a las 22:20


Avatar de usuario de Joachim W
Joaquín W.

Pitón 3:

print("fatal error", file=sys.stderr)

Pitón 2:

print >> sys.stderr, "fatal error"

Respuesta larga

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

Antiguo: print >> sys.stderr, "fatal error"

Nuevo: print("fatal error", file=sys.stderr)

Para muchos de nosotros, parece algo antinatural relegar el destino al final del comando. La alternativa

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

se ve más orientado a objetos y elegantemente va de lo genérico a lo específico. Pero ten en cuenta que write no es un reemplazo 1:1 para print.

  • Supongo que es una cuestión de preferencia, pero no veo qué tiene de feo. print('spam', file=sys.stderr). Si lo hace una y otra vez, puede codificar la función ‘eprint’ como en la respuesta más popular, pero en ese caso, preguntaría, ¿qué hay de malo en iniciar sesión? stackoverflow.com/a/41304513/1450294

    –Michael Scheper

    22 oct 2018 a las 18:33

  • Otra forma de aclarar la intención sería hacer with sys.stderr as dest: antes de una llamada sangrada a print("ERROR", file=dest)

    – MarkHu

    26 de agosto de 2019 a las 17:01

avatar de usuario de slushy
sentimentaloide

nadie es mencionado logging todavía, pero el registro se creó específicamente para comunicar mensajes de error. La configuración básica configurará un controlador de flujo que escribe en stderr.

Este guión:

# foo.py
import logging

logging.basicConfig(format="%(message)s")
log = logging.getLogger(__name__)
log.warning('I print to stderr by default')
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 barra.txt contendrá el ‘hola mundo’ impreso en la salida estándar.

Avatar de usuario de Frankovskyi Bogdan
frankovskyi bogdan

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

  • La forma más pitónica de imprimir un diccionario sería con algo como "{0}".format({'spam': 'spam'}) de todos modos, ¿no? Diría que debe evitar convertir explícitamente a una cadena. Editar: accidentalmente una gramática

    – luketparkinson

    23 de junio de 2012 a las 11:54


  • @luketparkinson se trata de la depuración, por lo que creo que es preferible usar el código más simple posible.

    – Frankovskyi Bogdan

    24 de marzo de 2013 a las 23:33

  • Esto no funciona en Python 3, por lo que debe evitarlo en el código nuevo.

    – JonnyJD

    23 de abril de 2013 a las 10:04

Yo diría que su primer enfoque:

print >> sys.stderr, 'spam' 

es el . . . obvio manera de hacerlo” Los otros no cumplen la regla #1 (“Hermoso es mejor que feo”).

— Editar para 2020 —

Arriba estaba mi respuesta para Python 2.7 en 2011. Ahora que Python 3 es el estándar, creo que la respuesta “correcta” es:

print("spam", file=sys.stderr) 

  • La forma más pitónica de imprimir un diccionario sería con algo como "{0}".format({'spam': 'spam'}) de todos modos, ¿no? Diría que debe evitar convertir explícitamente a una cadena. Editar: accidentalmente una gramática

    – luketparkinson

    23 de junio de 2012 a las 11:54


  • @luketparkinson se trata de la depuración, por lo que creo que es preferible usar el código más simple posible.

    – Frankovskyi Bogdan

    24 de marzo de 2013 a las 23:33

  • Esto no funciona en Python 3, por lo que debe evitarlo en el código nuevo.

    – JonnyJD

    23 de abril de 2013 a las 10:04

Hice lo siguiente usando Python 3:

from sys import stderr

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

Así que ahora puedo agregar argumentos de palabras 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")

  • Iba a sugerir que también podría usar un parcial, pero me di cuenta de que el parcial asigna el stderr a la función en el momento de la creación del parcial. Esto le impide redirigir stderr más tarde, ya que el parcial aún mantendrá el objeto stderr original.

    – Rebeldes

    30 de diciembre de 2013 a las 2:26


¿Ha sido útil esta solución?