Python stdout no se nivela correctamente después de llamar maldiciones
Pregunta
Tengo un programa que utiliza maldiciones, y luego vuelve al script principal para su posterior procesamiento. Después de que regrese, mi producción posterior a la salida estándar no aparece hasta que haya una gran cantidad de la misma (por ejemplo, miles de bytes).
He reducido el problema a un programa muy simple que no fiable:
import curses
import time
curses.initscr()
curses.endwin()
print "Hello world!"
time.sleep(5)
Si comento hacia fuera las dos llamadas maldiciones, el 'mundo Hola!' grabados antes de la demora. Si los pongo en, imprime después del retardo (al salir del script).
Solución
La llamada "curses.endwin()
conjuntos traseros estándar de E / S a la normalidad" ... que por desgracia significa "amortiguada" (se puede considerar que un error en curses
y presentar el fallo en perseguidor de Python).
Para asegurar estándar-salida es no tamponada,
import os
sys.stdout = os.fdopen(0, 'w', 0)
(Usted puede poner el import os
al comienzo, o curso; la reasignación de sys.stdout
tiene la intención de ir a la derecha después de la llamada endwin
).
Otros consejos
Alex me ganó de mano (él sabía, tenía que averiguarlo), pero me escribió este gestor de contexto ingenioso que es posible que pueda utilizar.
import curses
import time
import os
import sys
class CursesStdout(object):
def __enter__(self):
pass
def __exit__(self, *args):
sys.stdout = sys.__stdout__ = os.fdopen(sys.__stdout__.fileno(), 'w', 0)
with CursesStdout():
curses.initscr()
curses.endwin()
print "Hello world!"
time.sleep(2)
Me modificar sys.__stdout__
directamente porque cuando se mira a la fuente de curses/__init__.py
se ve que la función initscr
pasa ese descriptor de fichero con el código C y por lo almaceno que se restablezca a la normalidad.
forma más clara:
import sys
import curses
correct_stdout = sys.stdout # remember correct
curses.initscr()
curses.endwin()
sys.stdout = correct_stdout # restore correct
He encontrado que es tis System / Library dependiente. En mi máquina de Windows (maldiciones de http://www.lfd.uci.edu/~ Gohlke / pythonlibs / ) se vuelca y luego se duerme, pero en Linux se vuelca después de dormir. Creo que se puede utilizar simplemente: sys.stdout.flush()
como:
print "Hello world!"
sys.stdout.flush()
time.sleep(5)
(que puede ser mejor para hacer algún tipo de función "imprimir y al ras")