script - metodos en python
¿Cómo capturar salida stdout de una llamada de función Python? (3)
Echa un vistazo a este enlace sobre leer y escribir archivos en Python. Debería darle una idea de cómo escribir las cosas para archivar de varias maneras.
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 conocer 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 de do_something()
lleguen a este tema. Como solución alternativa, pensé en analizar lo que do_something()
escriba en stdout.
¿Cómo puedo capturar salida estándar entre dos puntos en el código, por ejemplo,
start_capturing()
do_something(my_object)
out = end_capturing()
?
En python> = 3.4, contextlib contiene un decorador redirect_stdout
. Se puede usar para responder a su pregunta de la siguiente manera:
import io
from contextlib import redirect_stdout
f = io.StringIO()
with redirect_stdout(f):
do_something(my_object)
out = f.getvalue()
De redirect_stdout :
Administrador de contexto para redirigir temporalmente sys.stdout a otro archivo u objeto similar a un archivo.
Esta herramienta agrega flexibilidad a las funciones existentes o clases cuya salida está cableada a stdout.
Por ejemplo, la salida de help () normalmente se envía a sys.stdout. Puede capturar esa salida en una cadena redireccionando la salida a un objeto io.StringIO:
f = io.StringIO() with redirect_stdout(f): help(pow) s = f.getvalue()
Para enviar la salida de help () a un archivo en disco, redirija la salida a un archivo normal:
with open(''help.txt'', ''w'') as f: with redirect_stdout(f): help(pow)
Para enviar el resultado de help () a sys.stderr:
with redirect_stdout(sys.stderr): help(pow)
Tenga en cuenta que el efecto secundario global en sys.stdout significa que este gestor de contexto no es adecuado para su uso en el código de la biblioteca y en la mayoría de las aplicaciones con subprocesos. Tampoco tiene ningún efecto en la salida de los subprocesos. Sin embargo, sigue siendo un enfoque útil para muchas secuencias de comandos de utilidad.
Este administrador de contexto es reentrante.
Pruebe este administrador de contexto:
from cStringIO import StringIO
import sys
class Capturing(list):
def __enter__(self):
self._stdout = sys.stdout
sys.stdout = self._stringio = StringIO()
return self
def __exit__(self, *args):
self.extend(self._stringio.getvalue().splitlines())
del self._stringio # free up some memory
sys.stdout = self._stdout
Uso:
with Capturing() as output:
do_something(my_object)
output
ahora es 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 se concatenan:
with Capturing() as output:
print ''hello world''
print ''displays on screen''
with Capturing(output) as output: # note the constructor argument
print ''hello world2''
print ''done''
print ''output:'', output
Salida:
displays on screen
done
output: [''hello world'', ''hello world2'']