Revisione dei requisiti
- usa
argparse
(ignorerò questo)
- consentire il richiamo di una o due azioni (almeno una richiesta).
- provalo con Pythonic (lo chiamerei piuttosto "POSIX")
Ci sono anche alcuni requisiti impliciti quando si vive sulla riga di comando:
- spiegare l'utilizzo all'utente in modo facile da capire
- le opzioni devono essere facoltative
- consente di specificare flag e opzioni
- consentire la combinazione con altri parametri (come nome file o nomi).
Soluzione di esempio utilizzando docopt
(file managelog.py
):
"""Manage logfiles
Usage:
managelog.py [options] process -- <logfile>...
managelog.py [options] upload -- <logfile>...
managelog.py [options] process upload -- <logfile>...
managelog.py -h
Options:
-V, --verbose Be verbose
-U, --user <user> Username
-P, --pswd <pswd> Password
Manage log file by processing and/or uploading it.
If upload requires authentication, you shall specify <user> and <password>
"""
if __name__ == "__main__":
from docopt import docopt
args = docopt(__doc__)
print args
Prova a eseguirlo:
$ python managelog.py
Usage:
managelog.py [options] process -- <logfile>...
managelog.py [options] upload -- <logfile>...
managelog.py [options] process upload -- <logfile>...
managelog.py -h
Mostra l'aiuto:
$ python managelog.py -h
Manage logfiles
Usage:
managelog.py [options] process -- <logfile>...
managelog.py [options] upload -- <logfile>...
managelog.py [options] process upload -- <logfile>...
managelog.py -h
Options:
-V, --verbose Be verbose
-U, --user <user> Username
-P, --pswd <pswd> P managelog.py [options] upload -- <logfile>...
Manage log file by processing and/or uploading it.
If upload requires authentication, you shall specify <user> and <password>
E usalo:
$ python managelog.py -V -U user -P secret upload -- alfa.log beta.log
{'--': True,
'--pswd': 'secret',
'--user': 'user',
'--verbose': True,
'-h': False,
'<logfile>': ['alfa.log', 'beta.log'],
'process': False,
'upload': True}
Alternativa breve short.py
Può esserci una variante anche più breve:
"""Manage logfiles
Usage:
short.py [options] (process|upload)... -- <logfile>...
short.py -h
Options:
-V, --verbose Be verbose
-U, --user <user> Username
-P, --pswd <pswd> Password
Manage log file by processing and/or uploading it.
If upload requires authentication, you shall specify <user> and <password>
"""
if __name__ == "__main__":
from docopt import docopt
args = docopt(__doc__)
print args
L'utilizzo è simile a questo:
$ python short.py -V process upload -- alfa.log beta.log
{'--': True,
'--pswd': None,
'--user': None,
'--verbose': True,
'-h': False,
'<logfile>': ['alfa.log', 'beta.log'],
'process': 1,
'upload': 1}
Nota che invece dei valori booleani per le chiavi "process" e "upload" ci sono dei contatori.
Si scopre che non possiamo impedire la duplicazione di queste parole:
$ python short.py -V process process upload -- alfa.log beta.log
{'--': True,
'--pswd': None,
'--user': None,
'--verbose': True,
'-h': False,
'<logfile>': ['alfa.log', 'beta.log'],
'process': 2,
'upload': 1}
Conclusioni
Progettare una buona interfaccia a riga di comando può essere difficile a volte.
Ci sono più aspetti del programma basato sulla riga di comando:
- buon design della riga di comando
- selezionando / utilizzando un parser appropriato
argparse
offre molto, ma limita gli scenari possibili e può diventare molto complesso.
Con le docopt
cose vanno molto più brevi preservando la leggibilità e offrendo un alto grado di flessibilità. Se riesci a ottenere argomenti analizzati dal dizionario ed esegui alcune conversioni (a interi, apertura di file ..) manualmente (o tramite un'altra libreria chiamata schema
), potresti trovare una docopt
buona soluzione per l'analisi da riga di comando.
-x
è universalmente una bandiera e facoltativa. Taglia il-
se necessario.