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.gameses negativo, pero tenía curiosidad por saber si había una manera de atraparlo en el argparsenivel, 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)
                
intfalla, ¿seguirá habiendo una salida legible? ¿O deberíatryraisela 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.typeserí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
choicesparámetro si también se conoce su límite superior:Nota: Use en
rangelugar dexrangepara python 3.xfuente
ifes 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
choicescon un rangofuente
Una alternativa más simple, especialmente si se subclasifican
argparse.ArgumentParser, es iniciar la validación desde el interior delparse_argsmé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
fooahora 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