Estoy usando una biblioteca de Python que hace algo con un objeto.
do_something(my_object)
y lo cambia. Mientras lo hace, imprime algunas estadísticas en stdout, y me gustaría controlar esta información. La solución adecuada sería cambiar do_something()
para devolver la información relevante,
out = do_something(my_object)
pero pasará un tiempo antes de que los desarrolladores do_something()
lleguen a este tema. Como solución alternativa, pensé en analizar todo lo que se do_something()
escribe en stdout.
¿Cómo puedo capturar la salida estándar entre dos puntos en el código, por ejemplo,
start_capturing()
do_something(my_object)
out = end_capturing()
?
Respuestas:
Prueba este administrador de contexto:
Uso:
output
es ahora una lista que contiene las líneas impresas por la llamada a la función.Uso avanzado:
Lo que puede no ser obvio es que esto se puede hacer más de una vez y los resultados concatenados:
Salida:
Actualización : Se añaden
redirect_stdout()
acontextlib
en Python 3.4 (junto conredirect_stderr()
). Así que podría usarloio.StringIO
para lograr un resultado similar (aunqueCapturing
podría decirse que ser una lista y un administrador de contexto es más conveniente).fuente
.extend()
lugar para que pudiera usarse de forma concatenativa, tal como lo notó. :-)self._stringio.truncate(0)
después de laself.extend()
llamada en el__exit__()
método para liberar parte de la memoria que tiene el_stringio
miembro.from io import StringIO
lugar de la primera línea en el administrador de contexto.En python> = 3.4, contextlib contiene un
redirect_stdout
decorador. Se puede usar para responder a su pregunta de la siguiente manera:De los documentos :
fuente
f = io.StringIO() with redirect_stdout(f): logger = getLogger('test_logger') logger.debug('Test debug message') out = f.getvalue() self.assertEqual(out, 'DEBUG:test_logger:Test debug message')
. Me da un error:AssertionError: '' != 'Test debug message'
logger.debug
no escribe en stdout por defecto. Si reemplaza su registro de llamadas conprint()
, debería ver el mensaje.stream_handler = logging.StreamHandler(sys.stdout)
. Y agregue ese controlador a mi registrador. así que debería escribir en stdout yredirect_stdout
debería capturarlo, ¿verdad?Aquí hay una solución asincrónica que usa canalizaciones de archivos.
Uso de ejemplo:
fuente