O título resume muito bem o que eu gostaria que acontecesse.
Aqui está o que eu tenho e, embora o programa não exploda um número inteiro não positivo, quero que o usuário seja informado de que um número inteiro não positivo é basicamente um disparate.
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-g", "--games", type=int, default=162,
help="The number of games to simulate")
args = parser.parse_args()
E a saída:
python simulate_many.py -g 20
Setting up...
Playing games...
....................
Saída com negativo:
python simulate_many.py -g -2
Setting up...
Playing games...
Agora, obviamente, eu poderia simplesmente adicionar um if para determinar que if args.games
é negativo, mas fiquei curioso para saber se havia uma maneira de capturá-lo no argparse
nível, para tirar proveito da impressão de uso automático.
Idealmente, imprimiria algo semelhante a este:
python simulate_many.py -g a
usage: simulate_many.py [-h] [-g GAMES] [-d] [-l LEAGUE]
simulate_many.py: error: argument -g/--games: invalid int value: 'a'
Igual a:
python simulate_many.py -g -2
usage: simulate_many.py [-h] [-g GAMES] [-d] [-l LEAGUE]
simulate_many.py: error: argument -g/--games: invalid positive int value: '-2'
Por enquanto estou fazendo isso e acho que estou feliz:
if args.games <= 0:
parser.print_help()
print "-g/--games: must be positive."
sys.exit(1)
int
falhar, ainda haverá uma saída legível? Ou você deve fazertry
raise
a conversão manualmente para isso?error: argument foo: invalid check_positive value: 'foo=<whatever>'
. Você pode simplesmente adicionar umtry:
... emexcept ValueError:
volta dele que gera uma exceção com uma mensagem de erro melhor.type
seria a opção recomendada para lidar com condições / verificações, como na resposta de Yuushi.No seu caso específico, você também pode usar o
choices
parâmetro se seu limite superior também for conhecido:Nota: use em
range
vez dexrange
para python 3.xfonte
if
é muito mais rápido.xrange
) e não requer código adicional. Essa troca está disponível. Cabe a cada um decidir qual caminho seguir.A maneira rápida e suja, se você tem um máximo previsível e um mínimo para o seu argumento, é usado
choices
com um intervalofonte
Uma alternativa mais simples, especialmente se a subclasse
argparse.ArgumentParser
, é iniciar a validação de dentro doparse_args
método.Dentro dessa subclasse:
Essa técnica pode não ser tão legal quanto uma chamada personalizada, mas faz o trabalho.
Sobre
ArgumentParser.error(message)
:Crédito: resposta por jonatan
fonte
print "-g/--games: must be positive."; sys.exit(1)
por apenasparser.error("-g/--games: must be positive.")
. (Uso como na resposta de Jonatan .)Caso alguém (como eu) se depare com essa pergunta em uma pesquisa no Google, aqui está um exemplo de como usar uma abordagem modular para resolver com perfeição o problema mais geral de permitir números inteiros argparse apenas em um intervalo especificado :
Isso permite que você faça algo como:
A variável
foo
agora permite apenas números inteiros positivos , como o OP solicitado.Observe que, além dos formulários acima, apenas um máximo também é possível com
IntRange
:fonte