Come acquisire l'output dell'interprete Python e/o CMD.EXE da uno script Python?

StackOverflow https://stackoverflow.com/questions/24931

  •  09-06-2019
  •  | 
  •  

Domanda

  1. È possibile acquisire l'output dell'interprete Python da uno script Python?
  2. È possibile acquisire l'output di Windows CMD da uno script Python?

Se sì, in quale libreria(y|ies) dovrei esaminare?

È stato utile?

Soluzione

Se stai parlando dell'interprete Python o di CMD.exe che è il "genitore" del tuo script, allora no, non è possibile.In ogni sistema tipo POSIX (ora stai utilizzando Windows, a quanto pare, e questo potrebbe avere qualche stranezza di cui non sono a conoscenza, YMMV) ogni processo ha tre flussi, input standard, output standard ed errore standard.Per impostazione predefinita (quando vengono eseguiti in una console) questi sono indirizzati alla console, ma il reindirizzamento è possibile utilizzando la notazione pipe:

python script_a.py | python script_b.py

Ciò lega il flusso di output standard dello script a al flusso di input standard dello script B.In questo esempio l'errore standard viene comunque inviato alla console.Vedi l'articolo su flussi standard suWikipedia.

Se stai parlando di un processo figlio, puoi avviarlo da Python in questo modo (stdin è anche un'opzione se desideri una comunicazione bidirezionale):

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()

Vedi il Pitone sottoprocesso modulo per informazioni sulla gestione del processo.Per la comunicazione, le pipe process.stdin e process.stdout sono considerate standard oggetti del file.

Da utilizzare con tubi, lettura da input standard come lassevk ti ha suggerito di fare qualcosa del genere:

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

sys.stdin e sys.stdout sono oggetti file standard come indicato sopra, definiti nel file sistema modulo.Potresti anche voler dare un'occhiata a tubi modulo.

Leggere i dati con readline() come nel mio esempio è però un modo piuttosto ingenuo di ottenere dati.Se l'output non è orientato alla linea o indeterministico, probabilmente vorrai esaminarlo sondaggio che sfortunatamente non funziona su Windows, ma sono sicuro che ci sia qualche alternativa là fuori.

Altri suggerimenti

Penso di poterti indicare una buona risposta per la prima parte della tua domanda.

1.È possibile catturare l'output di Python Interpreter da uno script Python?

La risposta è "", e personalmente mi piace quanto segue tratto dagli esempi in PEP 343 – La Dichiarazione “con”. 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 usato in questo modo:

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

Un aspetto interessante è che può essere applicato selettivamente solo attorno a una parte dell'esecuzione di uno script, piuttosto che alla sua intera estensione, e rimane in vigore anche quando vengono sollevate eccezioni non gestite nel suo contesto.Se riapri il file in modalità aggiunta dopo il primo utilizzo, puoi accumulare i risultati in un unico file:

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"

Naturalmente, quanto sopra potrebbe anche essere esteso anche al reindirizzamento sys.stderr allo stesso o ad un altro file.Vedi anche questo risposta a una domanda correlata.

In realtà puoi sicuramente, ed è bello, brutto e pazzesco allo stesso tempo!

È possibile sostituire sys.stdout e sys.stderr con oggetti StringIO che raccolgono l'output.

Ecco un esempio, salvalo come 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 esegui questo programma, vedrai che:

  • nulla è andato a stdout (dove print di solito viene stampato)
  • la prima stringa che viene scritta su stderr è quella che inizia con "It"
  • le due righe successive sono quelle raccolte nell'oggetto StringIO

Sostituire sys.stdout/err in questo modo è un'applicazione di ciò che viene chiamato MonkeyPatching.Le opinioni possono variare indipendentemente dal fatto che questo sia "supportato" o meno, ed è sicuramente un brutto trucco, ma mi ha salvato la pancetta quando ho provato a avvolgere cose esterne una o due volte.

Testato su Linux, non su Windows, ma dovrebbe funzionare altrettanto bene.Fammi sapere se funziona su Windows!

Tu vuoi sottoprocesso.Guarda specificamente Popen in 17.1.1 e comunica in 17.1.2.

In quale contesto lo stai chiedendo?

Stai cercando di acquisire l'output da un programma avviato dalla riga di comando?

se è così, ecco come eseguirlo:

somescript.py | your-capture-program-here

e per leggere l'output, basta leggere dallo standard input.

Se, d'altra parte, stai eseguendo quello script o cmd.exe o simili dall'interno del tuo programma, e vuoi aspettare fino al termine dello script/programma e catturarne tutto l'output, allora devi guardare la libreria chiamate che usi per avviare quel programma esterno, molto probabilmente c'è un modo per chiedergli di darti un modo per leggere l'output e attendere il completamento.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top