You are here: Partenza > Dive Into Python > Elaborare XML > Gestire gli argomenti da riga di comando | << >> | ||||
Dive Into PythonPython per programmatori esperti |
Python supporta pienamente la creazione di programmi che possono essere eseguiti da riga di comando, completi di argomenti, sia con flag nel formato breve che nel formato esteso per specificare le varie opzioni. Nessuno di questi è specifico di XML, ma questo script fa un buon uso dell'interpretazione da riga di comando, dunque pare un buon momento per menzionarla.
È difficile parlare dell'elaborazione da riga di comando senza prima capire come gli argomenti da riga di comando vengono presentati al programma Python, dunque scriviamo un semplice programma per vederli.
Se non lo avete ancora fatto, potete scaricare questo ed altri esempi usati in questo libro.
#argecho.py import sys for arg in sys.argv: print arg
[f8dy@oliver py]$ python argecho.py argecho.py [f8dy@oliver py]$ python argecho.py abc def argecho.py abc def [f8dy@oliver py]$ python argecho.py --help argecho.py --help [f8dy@oliver py]$ python argecho.py -m kant.xml argecho.py -m kant.xml
La prima cosa da sapere su sys.argv è che contiene il nome dello script che stiamo chiamando. Utilizzeremo questa conoscenza a nostro vantaggio più tardi, nel capitolo Programmazione orientata ai dati. Non preoccupatevi di questo per ora. | |
Gli argomenti da riga di comando sono separati da spazi ed ognuno di essi viene rappresentato da un elemento nella lista sys.argv. | |
Anche i flag da riga di comando, come --help, vengono rappresentati come elementi della lista sys.argv. | |
Per rendere le cose ancor più interessanti, alcuni flag da riga di comando possono a loro volta prendere degli argomenti. Per esempio, qui abbiamo il flag (-m) che prende un argomento (kant.xml). Entrambi, sia il flag che il suo argomento, sono semplicemente degli elementi sequenziali nella lista sys.argv. Non viene fatto alcun tentativo di associare l'uno con l'altro; tutto quello che ottenete è una lista. |
Come possiamo vedere, tutte le informazioni vengono passate da riga di comando ma non sembra che sia poi tutto così semplice da usare. Per programmi semplici che prendono un solo argomento e non hanno flag, potete semplicemente usare sys.argv[1] per leggere l'argomento. Non c'è vergogna in questo, io lo faccio sempre. Per programmi più complessi, avete bisogno del modulo getopt.
def main(argv): grammar = "kant.xml" try: opts, args = getopt.getopt(argv, "hg:d", ["help", "grammar="]) except getopt.GetoptError: usage() sys.exit(2) ... if __name__ == "__main__": main(sys.argv[1:])
Cosa sono dunque tutti questi parametri che passiamo alla funzione getopt? Beh, il primo è semplicemente una lista grezza dei flag e degli argomenti da riga di comando (escluso il primo elemento, il nome dello script, che abbiamo rimosso prima di chiamare la funzione main). Il secondo è la lista dei flag brevi che il nostro script accetta.
Il primo ed il terzo flag sono semplicemente dei flag autonomi; li potete specificare oppure no, fanno comunque qualcosa (stampa un aiuto) o cambiano uno stato (abilita il debugging). Comunque, il secondo flag (-g) deve essere seguito da un argomento, che è il nome del file di grammatica da cui leggere. Infatti può essere il nome di un file o un indirizzo web, e non sappiamo ancora quale (lo vedremo dopo), ma sappiamo che deve essere qualcosa. Dunque lo diciamo a getopt inserendo i due punti dopo g nel secondo parametro della funzione getopt.
Per complicare ulteriormente le cose, il nostro script accetta sia flag brevi (come -h) o lunghi (come --help), e vogliamo che facciano la stessa cosa. Questo è lo scopo del terzo parametro di getopt, specificare una lista di flag lunghi che corrispondono a quelli brevi specificati nel secondo parametro.
Ci sono tre cose da notare qui:
Ancora confusi? Diamo un'occhiata al codice e vediamo se ora ha più senso.
def main(argv): grammar = "kant.xml" try: except getopt.GetoptError: usage() sys.exit(2) for opt, arg in opts: if opt in ("-h", "--help"): usage() sys.exit() elif opt == '-d': global _debug _debug = 1 elif opt in ("-g", "--grammar"): grammar = arg source = "".join(args) k = KantGenerator(grammar, source) print k.output()
<< Create gestori separati per tipo di nodo |
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | |
Mettere tutto assieme >> |