You are here: Partenza > Dive Into Python > Elaborare XML > Standard input, output, ed error | << >> | ||||
Dive Into PythonPython per programmatori esperti |
Gli utenti UNIX hanno già familiarità con i concetti di standard input, standard output e standard error. Questa sezione è per il resto di voi.
Lo standard output e lo standard error (comunemente abbreviati come stdout e stderr) sono pipe integrate in ogni sistema UNIX. Quando stampate qualcosa, essa va alla pipe stdout; quando il vostro programma crasha e stampa informazioni di debug (come un traceback in Python), esse vanno alla pipe stderr. Entrambe queste pipe sono solitamente connesse al terminale video dove state lavorando, così quando un programma stampa, vedete l'output e quando un programma crasha, vedete informazioni di debug. Se state lavorando su un sistema con un IDE Python basato su finestra, stdout e stderr vanno direttamente alla vostra “Finestra interattiva”.
>>> for i in range(3): ... print 'Dive in' Dive in Dive in Dive in >>> import sys >>> for i in range(3): ... sys.stdout.write('Dive in') Dive inDive inDive in >>> for i in range(3): ... sys.stderr.write('Dive in') Dive inDive inDive in
Come abbiamo visto nell'Esempio 4.28, “Semplici contatori”, possiamo usare la funzione built-in range di Python per costruire semplici cicli contatori che ripetono qualcosa un certo numero di volte. | |
stdout è un oggetto simile a quello di un file; chiamando la sua funzione write stamperà qualsiasi stringa che voi gli diate. In effetti, questo è ciò che la funzione print fa realmente; aggiunge un ritorno di carrello (\r) alla fine della stringa che state stampando e chiama sys.stdout.write. | |
Nel caso più semplice, stdout ed stderr mandano il loro output nello stesso posto: l'IDE Python (se la state usando) o ad un terminale (se state usando Python dalla linea di comando). Come stdout, stderr non aggiunge i ritorni di carrello per voi; se li volete, dovete aggiungerli da soli. |
stdout e stderr sono entrambi oggetti di tipo file, come quelli discussi nella sezione Astrarre le sorgenti di ingresso, ma sono entrambi di sola scrittura. Non hanno un metodo read ma solo quello write. Inoltre, sono oggetti di tipo file, potete assegnargli qualunque altro oggetto file o simile a file per redirigere i loro output.
[f8dy@oliver kgp]$ python stdout.py Dive in [f8dy@oliver kgp]$ cat out.log This message will be logged instead of displayed
Se non lo avete ancora fatto, potete scaricare questo ed altri esempi usati in questo libro.
#stdout.py import sys print 'Dive in' saveout = sys.stdout fsock = open('out.log', 'w') sys.stdout = fsock print 'This message will be logged instead of displayed' sys.stdout = saveout fsock.close()
Redirigere stderr funziona esattamente allo stesso modo, usando sys.stderr invece di sys.stdout.
[f8dy@oliver kgp]$ python stderr.py [f8dy@oliver kgp]$ cat error.log Traceback (most recent line last): File "stderr.py", line 5, in ? raise Exception, 'this error will be logged' Exception: this error will be logged
Se non lo avete ancora fatto, potete scaricare questo ed altri esempi usati in questo libro.
#stderr.py import sys fsock = open('error.log', 'w') sys.stderr = fsock raise Exception, 'this error will be logged'
Standard input, per altri versi, è un oggetto file di sola lettura, rappresenta i dati che scorrono nel programma da qualche altro programma precedente. Questo non avrà molto senso per gli utenti del classico Mac OS, o anche agli utenti Windows che non hanno mai avuto a che fare con la linea di comando dell'MS-DOS. Il suo funzionamento consiste nel costruire una catena di comandi in una singola linea, così che l'output di un programma diventi l'input del prossimo programma della catena. Il primo programma si limita a scrivere sullo standard output (senza fare alcuna redirezione, solo normali istruzioni print o altro), il secondo programma legge dallo standard input ed il sistema operativo si prende cura di connettere l'output di un programma con l'input del seguente.
[f8dy@oliver kgp]$ python kgp.py -g binary.xml 01100111 [f8dy@oliver kgp]$ cat binary.xml <?xml version="1.0"?> <!DOCTYPE grammar PUBLIC "-//book.diveintopython.org//DTD Kant Generator Pro v1.0//EN" "kgp.dtd"> <grammar> <ref id="bit"> <p>0</p> <p>1</p> </ref> <ref id="byte"> <p><xref id="bit"/><xref id="bit"/><xref id="bit"/><xref id="bit"/>\ <xref id="bit"/><xref id="bit"/><xref id="bit"/><xref id="bit"/></p> </ref> </grammar> [f8dy@oliver kgp]$ cat binary.xml | python kgp.py -g - 10110001
Come abbiamo visto nella sezione Immergersi, in questo capitolo, questo codice stamperà una stringa di otto bit casuali, 0 o 1. | |
Questo codice stampa semplicemente l'intero contenuto di binary.xml. Gli utenti Windows dovrebbero usare type invece di cat. | |
Questo codice stampa il contenuto di binary.xml, ma il carattere “|”, chiamato carattere “pipe”, significa che il contenuto non verrà stampato sullo schermo. Al contrario diventerà input per il comando seguente, che in questo caso rappresenta il nostro script Python. | |
Invece di specificare un modulo (come binary.xml), specifichiamo “-”, che farà caricare al nostro script la grammatica dallo standard input invece che da un file sul disco (di più su come accade nel prossimo esempio). Così l'effetto è lo stesso della prima sintassi, dove specificammo il nome del file grammar direttamente, ma pensate alle possibile espansioni. Invece di fare semplicemente cat binary.xml, potremmo lanciare uno script che generi dinamicamente la grammatica, per poi redirigerlo nel nostro script. Può provenire da ovunque: un database, da meta-script generatori di grammatica o altro ancora. Il punto è che non dobbiamo cambiare il nostro script kgp.py completamente, per incorporare ognuna di queste funzionalità. Tutto quello che dobbiamo fare è essere capaci di prendere i file di grammatica dallo standard input, e separare tutta l'altra logica in un altro programma. |
Perciò come fa il nostro script “know” per leggere dallo standard input quando il file di grammatica è “-”? Non è magia, è solo codice.
def openAnything(source): if source == "-": import sys return sys.stdin # try to open with urllib (if source is http, ftp, or file URL) import urllib try: [... snip ...]
Questa è la funzione openAnything da toolbox.py, che abbiamo esaminato nella sezione Astrarre le sorgenti di ingresso. Tutto quello che abbiamo fatto è stato aggiungere tre linee di codice all'inizio della funzione per controllare se il sorgente è “-”; se si, ritorniamo sys.stdin. Veramente, avviene proprio questo! Ricordate, stdin è un oggetto simile ad un file con un metodo read, così il resto del nostro codice (in kgp.py, dove abbiamo chiamato openAnything) non viene modificato di un bit. |
<< Astrarre le sorgenti di ingresso |
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | |
Memorizzare i nodi e ricercarli >> |