El título resume bastante bien lo que me gustaría que sucediera.
Esto es lo que tengo, y aunque el programa no explota en un número entero no positivo, quiero que se informe al usuario que un número entero no positivo es básicamente una tontería.
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()
Y la salida:
python simulate_many.py -g 20
Setting up...
Playing games...
....................
Salida con un negativo:
python simulate_many.py -g -2
Setting up...
Playing games...
Ahora, obviamente, podría agregar un if para determinar que if args.games
es negativo, pero tenía curiosidad por saber si había una manera de atraparlo en el argparse
nivel, para aprovechar la impresión de uso automático.
Idealmente, imprimiría algo similar a esto:
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'
Al igual que:
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 ahora estoy haciendo esto, y creo que estoy feliz:
if args.games <= 0:
parser.print_help()
print "-g/--games: must be positive."
sys.exit(1)
int
falla, ¿seguirá habiendo una salida legible? ¿O deberíatry
raise
la conversión manualmente para eso?error: argument foo: invalid check_positive value: 'foo=<whatever>'
. Simplemente podría agregar untry:
...except ValueError:
alrededor que vuelva a generar una excepción con un mejor mensaje de error.type
sería la opción recomendada para manejar condiciones / controles, como en la respuesta de Yuushi.En su caso específico, también puede usar el
choices
parámetro si también se conoce su límite superior:Nota: Use en
range
lugar dexrange
para python 3.xfuente
if
es mucho más rápido.xrange
) y no requiere código adicional. Esa compensación está disponible. Depende de cada uno decidir qué camino tomar.La manera rápida y sucia, si tiene un máximo predecible y un mínimo para su arg, es usarlo
choices
con un rangofuente
Una alternativa más simple, especialmente si se subclasifican
argparse.ArgumentParser
, es iniciar la validación desde el interior delparse_args
método.Dentro de tal subclase:
Puede que esta técnica no sea tan buena como una llamada personalizada, pero hace el trabajo.
Acerca de
ArgumentParser.error(message)
:Crédito: respuesta por jonatan
fuente
print "-g/--games: must be positive."; sys.exit(1)
con soloparser.error("-g/--games: must be positive.")
. (Uso como en la respuesta de jonatan .)En caso de que alguien (como yo) se encuentre con esta pregunta en una búsqueda en Google, aquí hay un ejemplo de cómo usar un enfoque modular para resolver perfectamente el problema más general de permitir enteros argparse solo en un rango específico :
Esto le permite hacer algo como:
La variable
foo
ahora solo permite enteros positivos , como el OP solicitado.Tenga en cuenta que, además de los formularios anteriores, solo es posible un máximo con
IntRange
:fuente