optparse - Analizzatore di opzioni di riga di comando per rimpiazzare getopt

Scopo Analizzatore di opzioni di riga di comando per rimpiazzare getopt
Versione Python 2.3

Il modulo optparse è una moderna alternativa per l'analisi delle opzioni da riga di comando che offre diverse caratteristiche non disponibili in getopt, inclusa la conversione del tipo, il callback delle opzioni, e la generazione automatica dell'aiuto. Ci sono molte più caratteristiche di optparse di quelle che possono essere trattate qui, ma si spera che questa introduzione consenta di potere scrivere in poco tempo un programma da riga di comando.

Creare un OptionParser

Con optparse ci sono due fasi nell'elaborazione delle opzioni. Per primo viene costruita una istanza di OptionParser che viene poi configurata con le opzioni previste. Quindi una sequenza di opzioni viene ricevuta ed elaborata.

import optparse
parser = optparse.OptionParser()

In genere, una volta che il parser è stato creato, ogni opzione viene aggiunta al parser esplicitamente, con le informazioni rispetto a cosa fare quando l'opzione viene riscontrata nella riga di comando. E' anche possibilie passare un elenco di opzioni al costruttore di OptionParser, ma questa forma non sembra essere usata così frequentemente.

Definire le Opzioni

Le opzioni dovrebbero essere aggiunte una alla volta usando il metodo add_option(). Una qualsiasi stringa non nominata di parametri all'inizio dell'elenco dei parametri viene trattata come nome di opzione. Per creare alias per un'opzione, ad esempio per avere una forma breve ed una completa della stessa opzione basta passare entrambi i nomi.

A differenza di getopt, che elabora solamente le opzioni, optparse è una completa libreria per la elaborazione delle opzioni. Le opzioni possono attivare diverse azioni, specificate dal parametro action da passare ad add_option(). Le azioni supportate comprendono la memorizzazione del parametro (singolarmente o come parte di un elenco), la memorizzazione di un valore costante quando l'opzione viene rilevata (inclusa la getione speciale dei valori true/false per gli switch booleani), il contare il numero di volte in cui una opzione viene vista e la chiamata di un callback.

L'azione predefinita è la memorizzazione del parametro nell'opzione. In questo caso, se viene passato un tipo, il valore del parametro viene convertito in quel tipo prima di essere memorizzato. Se viene passato il parametro dest, il valore dell'opzione viene salvato in un attributo di quel nome nell'oggetto di opzioni restituito quando i parametri di riga di comando vengono analizzati.

Analizzare una Riga di Comando

Una volta che tutte le opzioni sono definite, la riga di comando viene analizzata passando una sequenza di stringhe di parametro a parse_args(). Nella modalità predefinita, i parametri sono presi da sys.argv[1:], ma è possibile anche passare la propria lista. Le opzioni sono elaborate usando la sintassi GNU/POSIX, in modo che le opzioni ed i valori dei parametri possano essere mescolati nella sequenza.

Il valore restituito da parse_args() è una tuple di due parti che contiene una istanza di optparse.Values e l'elenco dei parametri del comando che non sono stati interpretati come opzioni. L'istanza di Values contiene i valori dell'opzione come attributi, quindi se il valore di dest è "miaopzione", al suo valore si accede come options.miaopzione.

Semplici Esempi

Ecco un semplice esempio con tre opzioni diverse: una booleana (-a), una semplice opzione stringa (-b), ed una opzione integer (-c).

import optparse

parser = optparse.OptionParser()
parser.add_option('-a', action="store_true", default=False)
parser.add_option('-b', action="store", dest="b")
parser.add_option('-c', action="store", dest="c", type="int")

print parser.parse_args(['-a', '-bval', '-c', '3'])

Le opzioni nella riga di comando vengono analizzate con le stesse regole usate da getopt.gnu_getopt(), quindi ci sono due modi per passare i valori ad opzioni a carattere singolo. L'esempio di cui sopra usa entrambe le forme, -bval e -c val.

$ python optparse_short.py
(<Values at 0xb788940c: {'a': True, 'c': 3, 'b': 'val'}>, [])

Si noti che il tipo del valore associato a 'c' nell'output è un intero, visto che ad OptionParser è stato detto di convertire il parametro prima di conservarlo.

A differenza di getopt, nomi di opzione "lunghi" non sono trattati in modo diverso da optparse:

import optparse

parser = optparse.OptionParser()
parser.add_option('--noarg', action="store_true", default=False)
parser.add_option('--witharg', action="store", dest="witharg")
parser.add_option('--witharg2', action="store", dest="witharg2", type="int")

print parser.parse_args([ '--noarg', '--witharg', 'val', '--witharg2=3' ])

Ed i risultati sono simili:

$ python optparse_long.py
(<Values at 0x3b56c0: {'noarg': True, 'witharg': 'val', 'witharg2': 3}>, [])

Confronto con getopt

Ecco una implementazoine dello stesso programma di esempio usato nel capitolo riguardo a getopt:

import optparse
import sys

print 'ARGV       :', sys.argv[1:]

parser = optparse.OptionParser()
parser.add_option('-o', '--output',
                  dest="output_filename",
                  default="default.out",
                  )
parser.add_option('-v', '--verbose',
                  dest="verbose",
                  default=False,
                  action="store_true",
                  )
parser.add_option('--version',
                  dest="version",
                  default=1.0,
                  type="float",
                  )
options, remainder = parser.parse_args()

print 'VERSIONE   :', options.version
print 'VERBOSE    :', options.verbose
print 'OUTPUT     :', options.output_filename
print 'RIMANENTI  :', remainder

Si noti come le opzioni -o ed --output sono rese equivalenti aggiungendole allo stesso tempo. Entrambe le opzioni possono essere usate nella riga di comando. La forma breve:

$ python optparse_getoptcomparison.py -o output.txt
ARGV       : ['-o', 'output.txt']
VERSIONE   : 1.0
VERBOSE    : False
OUTPUT     : output.txt
RIMANENTI  : []

o la forma lunga:

$ python optparse_getoptcomparison.py --output output.txt
ARGV       : ['--output', 'output.txt']
VERSIONE   : 1.0
VERBOSE    : False
OUTPUT     : output.txt
RIMANENTI  : []

Può essere usato anche un qualsiasi prefisso univoco dell'opzione lunga:

$ python optparse_getoptcomparison.py --out output.txt
ARGV       : ['--out', 'output.txt']
VERSIONE   : 1.0
DETTAGLIATO: False
OUTPUT     : output.txt
RIMANENTI  : []

Callback alle Opzioni

A parte memorizzazione diretta dei parametri per le opzioni, è possibile definire delle funzioni di callback da chiamare quando l'opzione viene rilavata nella riga di comando. I callback per le opzioni ricevono 4 parametri: l'istanza di Option che sta causando il callback, la stringa dell'opzione da riga di comando, un qualsiasi valore di parametro associato all'opzione ed una istanza dell'OptionParser che sta eseguendo il lavoro di analisi.

import optparse

def flag_callback(option, opt_str, value, parser):
    print 'flag_callback:'
    print '\toption:', repr(option)
    print '\topt_str:', opt_str
    print '\tvalue:', value
    print '\tparser:', parser
    return

def with_callback(option, opt_str, value, parser):
    print 'with_callback:'
    print '\toption:', repr(option)
    print '\topt_str:', opt_str
    print '\tvalue:', value
    print '\tparser:', parser
    return

parser = optparse.OptionParser()
parser.add_option('--flag', action="callback", callback=flag_callback)
parser.add_option('--with',
                  action="callback",
                  callback=with_callback,
                  type="string",
                  help="Include caratteristiche opzionali")

parser.parse_args(['--with', 'foo', '--flag'])

In questo esempio l'opzione --with viene configurata per ottenere un parametro stringa (altri tipi come gli interi ed i valori a virgola mobile sono parimenti supportati).

$ python optparse_callback.py
with_callback:
        option: <Option at 0xb76f9eac: --with>
        opt_str: --with
        value: foo
        parser: <optparse.OptionParser instance at 0xb76f9bac>
flag_callback:
        option: <Option at 0xb76f9ccc: --flag>
        opt_str: --flag
        value: None
        parser: <optparse.OptionParser instance at 0xb76f9bac>

I callback possono essere configurati per ottenere parametri multipli usando l'opzione nargs.

import optparse

def with_callback(option, opt_str, value, parser):
    print 'with_callback:'
    print '\toption:', repr(option)
    print '\topt_str:', opt_str
    print '\tvalue:', value
    print '\tparser:', parser
    return

parser = optparse.OptionParser()
parser.add_option('--with',
                  action="callback",
                  callback=with_callback,
                  type="string",
                  nargs=2,
                  help="Include caratteristiche opzionali")

parser.parse_args(['--with', 'foo', 'bar'])

In questo caso i parametri sono passati alla funzione callback come una tuple attraverso il parametro value.

$ python optparse_callback_nargs.py
with_callback:
        option: 

Messaggi di Aiuto

OptionParser include automaticamente una opzione di aiuto per tutti gli insiemi di opzioni, quindi se l'utente passa --help in riga di comando vedrà le istruzioni per eseguire il programma. Il messaggio di aiuto comprende tutte le opzioni con un'indicazione del fatto che ricevano o meno un parametro. E' anche possibile passare un testo di aiuto ad add_option() per fornire una descrizione più dettagliata di una opzione.

import optparse

parser = optparse.OptionParser()
parser.add_option('--no-foo', action="store_true",
                  default=False,
                  dest="foo",
                  help="Disabilita foo",
                  )
parser.add_option('--with', action="store", help="Include caratteristiche opzionali")

parser.parse_args()

Le opzioni sono elencate in ordine alfabetico, con gli alias inclusi nella stessa riga. Quando un'opzione riceve un parametro il valore di dest viene incluso come nome del parametro nell'output di aiuto. Il testo di aiuto viene stampato nella colonna di destra.

$ python optparse_help.py --helpUsage: optparse_help.py [options]

Options:
  -h, --help   show this help message and exit
  --no-foo     Disabilita foo
  --with=WITH  Include caratteristiche opzionali

Vedere anche:

optparse
La documentazione della libreria standard per questo modulo.
getopt
Il modulo getopt
argparse
Rimpiazzo più recente per optparse.