¿Por qué la salida impresa no aparece inmediatamente en la terminal cuando no hay una nueva línea al final?
Tengo un script en Python que realiza una simulación. Se necesita un tiempo bastante largo y variable para ejecutar cada iteración, por lo que imprimo un .
después de cada bucle como una forma de monitorear qué tan rápido se ejecuta y hasta dónde llegó la for
declaración a medida que se ejecuta el script. Entonces el código tiene esta estructura general:
for step in steps:
run_simulation(step)
# Python 3.x version:
print('.', end='')
# for Python 2.x:
# print '.',
Sin embargo, cuando ejecuto el código, los puntos no aparecen uno por uno. En cambio, todos los puntos se imprimen a la vez cuando finaliza el bucle, lo que hace que todo el esfuerzo sea inútil. ¿Cómo puedo imprimir los puntos en línea mientras se ejecuta el código?
Este problema también puede ocurrir al iterar sobre datos provenientes de otro proceso e intentar imprimir resultados, por ejemplo para hacer eco de la entrada de una aplicación de Electron. Consulte Python no imprime la salida .
La cuestión
De forma predeterminada, la salida de un programa Python se almacena en un buffer para mejorar el rendimiento. La terminal es un programa separado de su código y es más eficiente almacenar texto y comunicarlo todo a la vez, en lugar de pedirle al programa de la terminal que muestre cada símbolo por separado.
Dado que los programas de terminal generalmente están destinados a usarse de forma interactiva, con la entrada y la salida avanzando una línea a la vez (por ejemplo, se espera que el usuario presione Enter para indicar el final de un único elemento de entrada), el valor predeterminado es almacenar en buffer la salida. una línea a la vez.
Entonces, si no se print
agrega ninguna nueva línea, la print
función (en 3.x; print
declaración en 2.x) simplemente agregará texto al búfer y no se mostrará nada.
Salida de otras maneras
De vez en cuando, alguien intentará generar resultados desde un programa Python utilizando directamente el flujo de salida estándar:
import sys
sys.stdout.write('test')
Esto tendrá el mismo problema: si la salida no termina con una nueva línea, permanecerá en el búfer hasta que se vacíe.
Solucionando el problema
por un soloprint
Podemos vaciar explícitamente la salida después de imprimir.
En 3.x, la print
función tiene un flush
argumento de palabra clave, que permite resolver el problema directamente:
for _ in range(10):
print('.', end=' ', flush=True)
time.sleep(.2) # or other time-consuming work
En 2.x, la print
declaración no ofrece esta funcionalidad. En su lugar, vacíe la secuencia explícitamente, utilizando su .flush
método. El flujo de salida estándar (donde va el texto cuando print
se edita, de forma predeterminada) está disponible mediante el sys
módulo de biblioteca estándar y se denomina stdout
. Así, el código quedará así:
for _ in range(10):
print '.',
sys.stdout.flush()
time.sleep(.2) # or other time-consuming work
Para múltiples print
s
En lugar de vaciar después de cada print
(o decidir cuáles necesitan vaciarse después), es posible desactivar completamente el almacenamiento en búfer de la línea de salida . Hay muchas formas de hacer esto, así que consulte la pregunta vinculada.