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:
outputes 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()acontextliben Python 3.4 (junto conredirect_stderr()). Así que podría usarloio.StringIOpara lograr un resultado similar (aunqueCapturingpodrí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_stringiomiembro.from io import StringIOlugar de la primera línea en el administrador de contexto.En python> = 3.4, contextlib contiene un
redirect_stdoutdecorador. 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.debugno 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_stdoutdebería capturarlo, ¿verdad?Aquí hay una solución asincrónica que usa canalizaciones de archivos.
Uso de ejemplo:
fuente