Revisão de Requisitos
- usar
argparse
(vou ignorar este)
- permitir que uma ou duas ações sejam chamadas (pelo menos uma é necessária).
- tente por Pythonic (prefiro chamá-lo de "POSIX")
Existem também alguns requisitos implícitos ao viver na linha de comando:
- explicar o uso para o usuário de uma maneira que seja fácil de entender
- as opções devem ser opcionais
- permite especificar sinalizadores e opções
- permite a combinação com outros parâmetros (como nome ou nomes de arquivo).
Solução de amostra usando docopt
(arquivo 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
Tente executá-lo:
$ python managelog.py
Usage:
managelog.py [options] process -- <logfile>...
managelog.py [options] upload -- <logfile>...
managelog.py [options] process upload -- <logfile>...
managelog.py -h
Mostre a ajuda:
$ 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 use-o:
$ 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 curta short.py
Pode haver uma variante ainda mais curta:
"""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
O uso é parecido com este:
$ 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}
Observe que, em vez de valores booleanos para as chaves de "processo" e "upload", existem contadores.
Acontece que não podemos evitar a duplicação dessas palavras:
$ 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}
Conclusões
Projetar uma boa interface de linha de comando pode ser um desafio às vezes.
Existem vários aspectos do programa baseado em linha de comando:
- bom design de linha de comando
- selecionando / usando o analisador adequado
argparse
oferece muito, mas restringe cenários possíveis e pode se tornar muito complexo.
Com as docopt
coisas ficam muito mais curtas, preservando a legibilidade e oferecendo alto grau de flexibilidade. Se você consegue obter argumentos analisados do dicionário e faz algumas conversões (para inteiro, abrindo arquivos ..) manualmente (ou por outra biblioteca chamada schema
), você pode achar um docopt
bom ajuste para análise de linha de comando.
-x
é universalmente uma bandeira e opcional. Corte o-
se for necessário.