2008-08-24 19 views

Respuesta

9

Si está hablando del intérprete de Python o CMD.exe que es el 'padre' de su secuencia de comandos, 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. predeterminado Bu (cuando se ejecuta en una consola) éstos se dirigen a la consola, pero redirección es posible usando la notación de la tubería:

python script_a.py | python script_b.py 

Esto ata el flujo de salida estándar de la escritura de una a la corriente de entrada estándar de escritura B. El error estándar todavía va a la consola en este ejemplo. Vea el artículo en standard streams en Wikipedia.

Si estamos hablando de un proceso hijo, puede iniciarlo desde pitón como tal (entrada estándar es también 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() 

Ver el módulo de Python para obtener información subprocess en la gestión del proceso. Para la comunicación, las tuberías process.stdin y process.stdout se consideran estándar file objects.

Para su uso con tubos, la lectura de la entrada estándar como lassevk sugirió que haría 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 señaló anteriormente, se define en la sys módulo. También es posible que desee echar un vistazo al módulo pipes.

La lectura de datos con readline() como en mi ejemplo es una forma ingenua de obtener datos. Si el resultado no está orientado a la línea o es indeterminista, probablemente desee consultar polling, que desafortunadamente no funciona en Windows, pero estoy seguro de que hay alguna alternativa.

+1

Tenga en cuenta que al invocar Python utilizando subprocess.Popen() a menudo es útil pasar el indicador "-u", que deshabilita el almacenamiento en búfer en stdin/stdout/stderr. Python no autoflush stdout cuando el niño comienza a leer stdin, si la salida ha sido redirigida a un conducto, por lo que puede terminar bloqueando para siempre la lectura de la salida que está almacenada. Me encontré con este problema tratando de envolver/automatizar pdb. –

0

¿En qué contexto estás preguntando?

¿Está tratando de capturar la salida de un programa que inicia 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, acabo de leer de la entrada estándar.

Si, por otro lado, está ejecutando ese script o cmd.exe o similar desde su programa, y ​​desea esperar hasta que el script/programa haya finalizado, y capturar todos sus resultados, entonces necesita Observe las llamadas de la biblioteca que usa para comenzar ese programa externo, lo más probable es que haya una manera de pedirle que le de una forma de leer la salida y esperar a que se complete.

1

Quiere subprocess. Mire específicamente a Popen en 17.1.1 y comuníquese en 17.1.2.

3

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.

He aquí un ejemplo, guardarlo 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 se ejecuta este programa, se verá que:

  • nada salió a la salida estándar (donde por lo general de impresión imprime a)
  • la primera cadena que se escribe en stderr es la que comienza con 'It'
  • las dos líneas siguientes son las que se recopilaron en el objeto StringIO

Reemplazando sys.stdout/err como esta 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!

4

Creo que puedo indicarle una buena respuesta para la primera parte de su pregunta.

1.     ¿Es posible capturar la salida del intérprete de Python desde un script en Python?

La respuesta es "sí ", y personalmente me gusta los siguientes levantada de los ejemplos en el documento PEP 343 -- The "with" Statement.

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 se utiliza de esta manera:

with stdout_redirected(open("filename.txt", "w")): 
    print "Hello world" 

Un aspecto agradable de esto es que se puede aplicar selectivamente en torno a sólo una parte de la ejecución de una secuencia de comandos, en lugar de toda su extensión, y permanece en vigor incluso cuando se plantean excepciones no controladas dentro de su contexto. Si se vuelve a abrir el archivo en modo de adición del modo después de su primer uso, se 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 se podría extender también redirigir sys.stderr a la misma o otro archivo. También vea esto answer a una pregunta relacionada.

Cuestiones relacionadas