¿Por qué la salida impresa no aparece inmediatamente en la terminal cuando no hay una nueva línea al final?

Resuelto LWZ asked hace 10 años • 1 respuestas

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 fordeclaració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 .

LWZ avatar Sep 18 '14 01:09 LWZ
Aceptado

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 printagrega ninguna nueva línea, la printfunción (en 3.x; printdeclaració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 printfunción tiene un flushargumento 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 printdeclaración no ofrece esta funcionalidad. En su lugar, vacíe la secuencia explícitamente, utilizando su .flushmétodo. El flujo de salida estándar (donde va el texto cuando printse edita, de forma predeterminada) está disponible mediante el sysmó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 prints

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.

Karl Knechtel avatar Sep 17 '2014 18:09 Karl Knechtel