example español check_output python python-2.7 printing stderr zen

check_output - subprocess python español



¿Cómo imprimir a stderr en Python? (15)

He encontrado varias maneras de escribir a 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 contradecir el zen de Python # 13 , entonces, ¿cuál es la forma preferida de hacerlo? ¿Hay ventajas o desventajas de una manera u otra?

Debe haber una, y preferiblemente solo una, manera obvia de hacerlo.


La respuesta a la pregunta es: hay diferentes maneras de imprimir stderr en python, pero eso depende de 1.) qué versión de python estamos usando 2.) qué resultado exacto queremos.

La diferencia entre la impresión y la función de escritura de stderr : stderr : stderr (error estándar) es una canalización integrada en cada sistema UNIX / Linux, cuando su programa falla e imprime información de depuración (como un rastreo en Python), va al stderr tubo.

print : print es un contenedor que formatea las entradas (la entrada es el espacio entre el argumento y la nueva línea al final) y luego llama a la función de escritura de un objeto dado, el objeto dado por defecto es sys.stdout, pero podemos pasar un archivo, es decir, podemos imprimir la entrada en un archivo también.

Python2: Si estamos usando python2 entonces

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

La coma final de Python2 se ha convertido en un parámetro en Python3, por lo que si usamos comas finales para evitar la nueva línea después de una impresión, en Python3 se verá como una impresión (''Text to print'', end = '''') que es un error de sintaxis en Python2 .

http://python3porting.com/noconv.html

Si comprobamos lo mismo arriba sceario en python3:

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

Bajo Python 2.6 hay una importación futura para hacer imprimir en una función. Por lo tanto, para evitar errores de sintaxis y otras diferencias, deberíamos iniciar cualquier archivo en el que usemos print () con la función de importación de impresión futura . La importación futura solo funciona bajo Python 2.6 y versiones posteriores, así que para Python 2.5 y versiones anteriores tiene dos opciones. Puede convertir la impresión más compleja en algo más simple, o puede usar una función de impresión independiente que funcione tanto con Python2 como con Python3.

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

Caso: debe señalarse que sys.stderr.write () o sys.stdout.write () (stdout (salida estándar) es una canalización que está integrada en todos los sistemas UNIX / Linux) no es un reemplazo para la impresión, pero sí Podemos usarlo como alternativa en algún caso. Imprimir es un contenedor que envuelve la entrada con espacio y nueva línea al final y utiliza la función de escritura para escribir. Esta es la razón por la que sys.stderr.write () es más rápido.

Nota: también podemos rastrear y depurar utilizando el registro.

#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


Descubrí que este es el único legible + corto + flexible + portátil +:

from __future__ import print_function import sys def eprint(*args, **kwargs): print(*args, file=sys.stderr, **kwargs)

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

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


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

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


Estoy trabajando en python 3.4.3. Estoy cortando un poco de escritura que muestra cómo llegué aquí:

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

¿Funcionó? Intente redirigir stderr a un archivo y vea qué sucede:

[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]$

Bueno, aparte del hecho de que la pequeña introducción que Python te da ha sido introducida en stderr (¿a dónde más iría?), Funciona.


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


Lo mismo se aplica a stdout:

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

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

  1. Más tarde puede decidir cambiar entre stdout / stderr y un archivo normal.

  2. La sintaxis de print () ha cambiado en Python 3, por lo que si necesita admitir ambas versiones, write () podría ser mejor.


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

# foo.py import logging logging.basicConfig(format=''%(message)s'') logging.warning(''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'')

(Tenga en cuenta que logging.warn ha quedado en deprecated , use logging.warning en logging.warning lugar)


Para Python 2, mi elección es: print >> sys.stderr, ''spam'' ya que simplemente puede imprimir listas / dados, etc. sin convertirlo en una cadena. print >> sys.stderr, {''spam'': ''spam''} lugar de: sys.stderr.write(str({''spam'': ''spam''}))


Si haces una prueba simple:

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

¡Encontrará que sys.stderr.write () es consistentemente 1.81 veces más rápido!


Tratar:

from sys import stderr print >> sys.stderr, ''spam''


Yo diría que su primer acercamiento:

print >> sys.stderr, ''spam''

es la "Una... manera obvia de hacerlo". Las otras no cumplen con la regla # 1 ("Bello es mejor que feo").


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 tenga en cuenta que write no es un reemplazo 1: 1 para print .


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

Edición: 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 tan a menudo (legibilidad).


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 usar una función simple como otros han señalado.

Usando parcial solo te guarda 1 línea de código. La confusión potencial no vale la pena 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 para envolver funciones.

from __future__ import print_function import sys from functools import partial error = partial(print, file=sys.stderr)

Entonces lo usas como tal

error(''An error occured!'')

Puede verificar que se está imprimiendo en stderr y no en stdout haciendo lo siguiente (código superior 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 que parcial asigna el valor de sys.stderr a la función ajustada en el momento de la creación. Lo que significa que, si redirecciona stderr más tarde, no afectará a esta función. Si planea redireccionar stderr, use el método ** kwargs mencionado por aaguirre en esta página.


import logging logging.basicConfig(format=''[%(levelname)s] %(message)s'') logging.error(''is error, alarm!'') logging.warning(''is simple waring'') print(''hello'')

registro pydoc