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
.