Esta resposta vem de Steven Bethard nos grupos do Google . Estou publicando aqui para facilitar o acesso de pessoas sem uma Conta do Google.
Você pode substituir o comportamento padrão do error
método:
import argparse
import sys
class MyParser(argparse.ArgumentParser):
def error(self, message):
sys.stderr.write('error: %s\n' % message)
self.print_help()
sys.exit(2)
parser = MyParser()
parser.add_argument('foo', nargs='+')
args = parser.parse_args()
Observe que a solução acima imprimirá a mensagem de ajuda sempre que o error
método for acionado. Por exemplo, test.py --blah
também imprimirá a mensagem de ajuda se --blah
não for uma opção válida.
Se você deseja imprimir a mensagem de ajuda apenas se nenhum argumento for fornecido na linha de comando, talvez essa ainda seja a maneira mais fácil:
import argparse
import sys
parser=argparse.ArgumentParser()
parser.add_argument('foo', nargs='+')
if len(sys.argv)==1:
parser.print_help(sys.stderr)
sys.exit(1)
args=parser.parse_args()
Observe que, parser.print_help()
por padrão, imprime em stdout. Como init_js sugere , use parser.print_help(sys.stderr)
para imprimir em stderr.
parser.print_usage()
no lugar deparser.print_help()
- a mensagem de ajuda inclui o uso, mas é mais detalhada.error()
parece uma péssima idéia. Ele serve a um propósito diferente, não foi projetado para imprimir uma ajuda ou uso amigável.Em vez de escrever uma classe, uma tentativa / exceção pode ser usada
A vantagem é que o fluxo de trabalho é mais claro e você não precisa de uma classe de stub. A desvantagem é que a primeira linha de 'uso' é impressa duas vezes.
Isso precisará de pelo menos um argumento obrigatório. Sem argumentos obrigatórios, é válido fornecer zero args na linha de comando.
fonte
-h
sinalizador for usado e impressões desnecessárias ajudam se o--version
sinalizador for usado. Para mitigar esses problemas, você pode verificar o tipo de erro como este:except SystemExit as err: if err.code == 2: parser.print_help()
Com argparse você pode fazer:
fonte
parser.parse_args()
Se você tiver argumentos que devem ser especificados para a execução do script - use o parâmetro necessário para ArgumentParser, como mostrado abaixo: -
parse_args () relatará um erro se o script for executado sem argumentos.
fonte
Se você associar funções padrão para (sub) analisadores, conforme mencionado em
add_subparsers
, você pode simplesmente adicioná-lo como a ação padrão:Adicione a tentativa, exceto se você criar exceções devido à falta de argumentos posicionais.
fonte
A solução mais limpa será passar manualmente o argumento padrão se nenhum foi fornecido na linha de comando:
Exemplo completo:
Isso imprimirá a ajuda completa (não de uso curto) se for chamado sem argumentos.
fonte
sys.argv[1:]
é um idioma muito comum. Eu vejoparser.parse_args(None if sys.argv[1:] else ['-h'])
mais idiomática e mais limpa.Jogando minha versão na pilha aqui:
Você pode notar o
parser.exit
- eu faço isso principalmente porque salva uma linha de importação, se esse foi o único motivo parasys
o arquivo ...fonte
not vars(args)
pode não funcionar quando os argumentos têmdefault
método.Há um par de one-liners com
sys.argv[1:]
(o idioma do Python muito comum para referenciar os argumentos da linha de comando, sendosys.argv[0]
o nome do script) que podem fazer o trabalho.O primeiro é auto-explicativo, limpo e pitônico:
O segundo é um pouco mais hackier. Combinando o fato avaliado anteriormente de que uma lista vazia está
False
com oTrue == 1
False == 0
equivalências e, você obtém o seguinte:Talvez muitos colchetes, mas muito claro se uma seleção de argumento anterior foi feita.
fonte
O
parser.exit
método também aceita umstatus
(código de retorno) e ummessage
valor (inclua uma nova linha à direita!).um exemplo opinativo :)
Chamadas de exemplo:
fonte
Defina seus argumentos posicionais com nargs e verifique se os argumentos posicionais estão vazios.
Referência Python nargs
fonte
Aqui está outra maneira de fazer isso, se você precisar de algo flexível, onde deseja exibir ajuda se parâmetros específicos forem passados, nenhum ou mais que um argumento conflitante:
Felicidades!
fonte
Se seu comando for algo em que um usuário precise escolher alguma ação, use um grupo mutuamente exclusivo com required = True .
Isso é uma extensão da resposta dada pelo pd321.
Resultado:
Isso apenas dá a ajuda básica. E algumas das outras respostas lhe darão a ajuda completa. Mas pelo menos seus usuários sabem que podem fazer -h
fonte
Isso não é bom (também porque intercepta todos os erros), mas:
Aqui está a definição da
error
função daArgumentParser
classe:https://github.com/python/cpython/blob/276eb67c29d05a93fbc22eea5470282e73700d20/Lib/argparse.py#L2374
. Como você vê, após a assinatura, são necessários dois argumentos. No entanto, funções fora da classe nada sabem sobre o primeiro argumento:
self
porque, grosso modo, esse é um parâmetro para a classe. (Eu sei, que você sabe ...) Assim, basta passar própriaself
emessage
em_error(...)
não pode (irá produzir:
) Você pode passar
parser
(self
) na_error
função, chamando-a:, mas você não deseja sair do programa no momento. Depois devolva:
. No entanto,
parser
não sabe, que ele foi modificado; assim, quando ocorrer um erro, ele será responsável (a propósito, sua tradução localizada). Bem, então intercepte:. Agora, quando ocorrer um erro e
parser
enviar sua causa, você o interceptará, examinará isso e ... jogará fora.fonte