Python argparse saltar si no es int

Me gustaría tener 3 argumentos posicionales opcionales ( int , int , luego str ).

Lo que quiero:

 $ ./args.py 0 100 vid start=0 end=100 video='vid' $ ./args.py 0 100 start=0 end=100 video=None $ ./args.py 0 start=0 end=None video=None $ ./args.py vid start=None end=None video='vid' $ ./args.py start=None end=None video=None 

Lo que he intentado:

 #!/usr/bin/python3 import argparse parser = argparse.ArgumentParser() parser.add_argument('start', type=int, nargs='?') parser.add_argument('end', type=int, nargs='?') parser.add_argument('video', type=str, nargs='?') print(parser.parse_args()) 

El problema con ese código es:

 $ ./args.py vid usage: args.py [-h] [start] [end]  args.py: error: argument start: invalid int value: 'vid' 

argparse sabe que el valor ‘vid’ no es un entero, por lo que me gustaría que “omita” los dos primeros argumentos start y end ya que no coinciden.

Cuando hago que el argumento del video obligatorio, funciona un poco mejor:

 parser.add_argument('start', type=int, nargs='?') parser.add_argument('end', type=int, nargs='?') parser.add_argument('video', type=str) 

Manifestación:

 # Fine! $ ./args.py 0 100 vid start=0 end=100 video='vid' # Fine! $ ./args.py vid start=None end=None video='vid' # Not fine ./args.py usage: args.py [-h] [start] [end] video args.py: error: the following arguments are required: video 

No hay una forma integrada de hacer esto de manera limpia, creo. Por lo tanto, solo tendrás que reunir todas las opciones en una lista y analizarlas tú mismo.

p.ej

 parser.add_argument('start_end_video', nargs='*') args=parser.parse_args() if len(args.start_end_video) == 1: video = args.start_end_video elif len(args.start_end_video) == 3: start, end, video = args.start_end_video 

etc.

Creo que deberías agregar lo que se llaman tus argumentos:

 import argparse parser = argparse.ArgumentParser() parser.add_argument('-s', '--start', type=int) parser.add_argument('-e', '--end', type=int) parser.add_argument('-v', '--video', type=str) args = parser.parse_args() for arg in vars(args): print(arg, '=', getattr(args, arg)) 

De esa manera puede especificar los argumentos y no se puede producir confusión:

 $ ./args.py -s 0 -e 100 -v vid start = 0 end = 100 video = vid $ ./args.py -s 0 -e 100 start = 0 end = 100 video = None $ ./args.py -s 0 start = 0 end = None video = None $ ./args.py -v vid start = None end = None video = vid $ ./args.py start = None end = None video = None $ ./args.py vid usage: args.py [-h] [-s START] [-e END] [-v VIDEO] args.py: error: unrecognized arguments: vid 

Nota: He incluido alias cortos en los argumentos anteriores. Por ejemplo, puedes llamar -s lugar de --start .