programa - ¿Cómo capturar el resultado del intérprete de Python y/o CMD.EXE de un script de Python?
python en windows 10 (5)
- ¿Es posible capturar el resultado del intérprete de Python desde un script de Python?
- ¿Es posible capturar el resultado de CMD de Windows desde un script de Python?
Si es así, ¿qué biblioteca (y | ies) debo buscar?
¿En qué contexto estás preguntando?
¿Estás tratando de capturar el resultado de un programa que comienzas en la línea de comando?
si es así, entonces esta es la forma de ejecutarlo:
somescript.py | your-capture-program-here
y para leer la salida, simplemente lea desde la entrada estándar.
Si, por otro lado, está ejecutando ese script o cmd.exe o similar desde dentro de su programa, y quiere esperar hasta que el script / programa haya finalizado, y capture todo su resultado, entonces necesita mirar la biblioteca llamadas que usa para iniciar ese programa externo, lo más probable es que haya una manera de pedirle que le de una forma de leer el resultado y esperar a que se complete.
Quieres un subproceso Mire específicamente a Popen en 17.1.1 y comuníquese en 17.1.2.
En realidad, definitivamente puedes, y es hermoso, feo y loco al mismo tiempo.
Puede reemplazar sys.stdout y sys.stderr con objetos StringIO que recogen la salida.
Aquí hay un ejemplo, guárdelo como evil.py:
import sys
import StringIO
s = StringIO.StringIO()
sys.stdout = s
print "hey, this isn''t going to stdout at all!"
print "where is it ?"
sys.stderr.write(''It actually went to a StringIO object, I will show you now:/n'')
sys.stderr.write(s.getvalue())
Cuando ejecutas este programa, verás que:
- nada fue a stdout (donde la impresión generalmente se imprime)
- la primera cadena que se escribe en stderr es la que comienza con ''It''
- las siguientes dos líneas son las que se recopilaron en el objeto StringIO
Reemplazar sys.stdout / err como este es una aplicación de lo que se llama monkeypatching. Las opiniones pueden variar tanto si esto es ''compatible'' como si no, y definitivamente es un hack feo, pero me ha salvado el tocino cuando intento envolver cosas externas una o dos veces.
Probado en Linux, no en Windows, pero debería funcionar igual de bien. ¡Avíseme si funciona en Windows!
Creo que puedo señalarte una buena respuesta para la primera parte de tu pregunta.
1. ¿Es posible capturar el resultado del intérprete de Python desde un script de Python?
La respuesta es " sí ", y personalmente me gustaría que se eliminase de los ejemplos en el PEP 343 - El documento de declaración "con" .
from contextlib import contextmanager
import sys
@contextmanager
def stdout_redirected(new_stdout):
saved_stdout = sys.stdout
sys.stdout = new_stdout
try:
yield None
finally:
sys.stdout.close()
sys.stdout = saved_stdout
Y usado así:
with stdout_redirected(open("filename.txt", "w")):
print "Hello world"
Un buen aspecto de esto es que se puede aplicar selectivamente solo alrededor de una parte de la ejecución de un script, en lugar de en toda su extensión, y permanece en vigencia incluso cuando se generan excepciones no controladas dentro de su contexto. Si vuelve a abrir el archivo en el modo de agregar después de su primer uso, puede acumular los resultados en un solo archivo:
with stdout_redirected(open("filename.txt", "w")):
print "Hello world"
print "screen only output again"
with stdout_redirected(open("filename.txt", "a")):
print "Hello world2"
Por supuesto, lo anterior también podría extenderse para redirigir también sys.stderr
al mismo u otro archivo. También vea esta respuesta a una pregunta relacionada.
Si está hablando del intérprete de Python o CMD.exe que es el ''padre'' de su script, entonces no, no es posible. En cada sistema similar a POSIX (ahora está ejecutando Windows, parece, y eso podría tener alguna peculiaridad que desconozco, YMMV) cada proceso tiene tres flujos, entrada estándar, salida estándar y error estándar. Bu predeterminado (cuando se ejecuta en una consola) estos se dirigen a la consola, pero la redirección es posible usando la notación de canalización:
python script_a.py | python script_b.py
Esto vincula el flujo de salida estándar del script a al flujo de entrada estándar del script B. El error estándar todavía va a la consola en este ejemplo. Vea el artículo sobre transmisiones estándar en Wikipedia.
Si está hablando de un proceso hijo, puede iniciarlo desde python de esa manera (stdin también es una opción si desea una comunicación bidireccional):
import subprocess
# Of course you can open things other than python here :)
process = subprocess.Popen(["python", "main.py"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
x = process.stderr.readline()
y = process.stdout.readline()
process.wait()
Consulte el módulo de subproceso de Python para obtener información sobre la administración del proceso. Para la comunicación, las tuberías process.stdin y process.stdout se consideran objetos de archivo estándar.
Para usar con tuberías, leer de la entrada estándar como lassevk sugirió que harías algo como esto:
import sys
x = sys.stderr.readline()
y = sys.stdin.readline()
sys.stdin y sys.stdout son objetos de archivo estándar como se indicó anteriormente, definidos en el módulo sys . También es posible que desee echar un vistazo al módulo de tuberías .
La lectura de datos con readline () como en mi ejemplo es una forma ingenua de obtener datos. Si la salida no está orientada a la línea o es indeterminista, probablemente desee examinar las encuestas, lo que desafortunadamente no funciona en Windows, pero estoy seguro de que hay alguna alternativa.