Como capturar o intérprete de Python e / ou saída do CMD.EXE a partir de um script Python?

votos
7
  1. É possível capturar a saída do Python intérprete a partir de um script Python?
  2. É possível capturar a saída do Windows CMD de um script Python?

Se assim for, o que librar (y | ies) eu deveria olhar para?

Publicado 24/08/2008 em 09:46
fonte usuário
Em outras línguas...                            


5 respostas

votos
9

Se você está falando sobre o interpretador Python ou CMD.exe que é o 'pai' do seu script, então não, não é possível. Em todos os sistemas POSIX-like (agora você está executando o Windows, ao que parece, e que pode ter alguma peculiaridade que eu não sei sobre, YMMV) cada processo tem três correntes, entrada padrão, saída padrão e erro padrão. Bu padrão (quando executado em um console) estes são direcionados para o console, mas o redirecionamento é possível usando a notação da tubulação:

python script_a.py | python script_b.py

Esta liga o fluxo de saída padrão de script de um para o fluxo de entrada padrão do script de erro B. Padrão ainda vai para o console neste exemplo. Veja o artigo sobre fluxos padrão na Wikipedia.

Se você está falando de um processo filho, você pode iniciá-lo em python assim (stdin também é uma opção se você quiser comunicação 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()

Veja o Python subprocesso módulo para obter informações sobre a gestão do processo. Para a comunicação, os tubos process.stdin e process.stdout são considerados padrão objetos de arquivo .

Para uso com tubos, a leitura da entrada padrão como lassevk sugeriu você faria algo assim:

import sys
x = sys.stderr.readline()
y = sys.stdin.readline()

sys.stdin e sys.stdout são objectos de ficheiros convencionais, como indicado acima, definido na sys módulo. Você também pode querer dar uma olhada no pipes módulo.

Leitura de dados com readline () como no meu exemplo é uma maneira muito ingênua da obtenção de dados embora. Se a saída não é a linha-orientado ou indeterminística você provavelmente vai querer olhar para polling que infelizmente não funciona no Windows, mas eu tenho certeza que há alguma alternativa lá fora.

Respondeu 24/08/2008 em 10:39
fonte usuário

votos
4

Eu acho que você pode apontar para uma boa resposta para a primeira parte da sua pergunta.

1. É possível capturar a saída do Python intérprete a partir de um script Python?

A resposta é " sim ", e pessoalmente eu como o seguinte levantada a partir dos exemplos na PEP 343 - A "com" Declaração documento.

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

E usado como este:

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

Um aspecto interessante de tudo é que ele pode ser aplicado seletivamente em torno de apenas uma parte da execução de um roteiro, em vez de toda a sua extensão, e permanece em vigor mesmo quando não manipulado exceções são levantadas dentro de seu contexto. Se você re-abrir o arquivo em modo de adição após seu primeiro uso, você pode acumular os resultados em um único arquivo:

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"

Claro, o acima também poderia ser estendido para redirecionar também sys.stderrpara o mesmo ou outro arquivo. Veja também esta resposta a uma pergunta relacionada.

Respondeu 31/07/2010 em 17:40
fonte usuário

votos
3

Na verdade, você pode definitivamente, e é bonito, feio, e louco ao mesmo tempo!

Você pode substituir sys.stdout e sys.stderr com objetos StringIO que coletam a saída.

Aqui está um exemplo, salve-o 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())

Quando você executar este programa, você vai ver que:

  • nada foi para stdout (onde impressão normalmente imprime a)
  • a primeira cadeia que é escrita para stderr é aquele que começa com 'It'
  • As duas linhas seguintes são os que foram recolhidos no objecto StringIO

Substituindo sys.stdout / err como esta é uma aplicação do que é chamado monkeypatching. Opiniões podem variar ou não isso é 'suportado', e é definitivamente uma gambiarra, mas salvou meu bacon ao tentar envolver em torno de material externo uma ou duas vezes.

Testado em Linux, não no Windows, mas deve funcionar tão bem. Deixe-me saber se ele funciona no Windows!

Respondeu 27/08/2008 em 00:16
fonte usuário

votos
1

Você quer subprocesso . Analisar especificamente Popen em 17.1.1 e se comunicar em 17.1.2.

Respondeu 24/08/2008 em 10:27
fonte usuário

votos
0

Em que contexto você está perguntando?

Você está tentando capturar a saída de um programa que você começar na linha de comando?

se assim for, então esta é a forma de executá-lo:

somescript.py | your-capture-program-here

e ler a saída, basta ler da entrada padrão.

Se, por outro lado, você está executando esse script ou cmd.exe ou similar dentro de seu programa, e quer esperar até que o script / programa terminar, e capturar toda a sua saída, então você precisa olhar para a biblioteca chama você usa para iniciar o programa externo, provavelmente há uma maneira de pedir-lhe para lhe dar alguma maneira de ler a saída e aguardar a conclusão.

Respondeu 24/08/2008 em 10:05
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more