Cómo analizar argumentos posicionales con el signo menos inicial (números negativos) usando argparse

Me gustaría analizar un argumento posicional requerido que contenga una lista de enteros separados por comas. Si el primer entero contiene un signo menos (‘-‘) inicial, argparse se queja:

import argparse parser = argparse.ArgumentParser() parser.add_argument('positional') parser.add_argument('-t', '--test', action='store_true') opts = parser.parse_args() print opts $ python example.py --test 1,2,3,4 Namespace(positional='1,2,3,4', test=True) $ python example.py --test -1,2,3,4 usage: example.py [-h] [-t] positional example.py: error: too few arguments $ python example.py --test "-1,2,3,4" usage: example.py [-h] [-t] positional example.py: error: too few arguments 

He visto a otras personas sugerir el uso de algún otro personaje además - como el personaje de la bandera, pero prefiero no hacerlo. ¿Hay otra forma de configurar argparse para permitir que tanto --test como -1,2,3,4 argumentos válidos?

Necesita insertar un -- en sus argumentos de línea de comando:

 $ python example.py --test -- -1,2,3,4 Namespace(positional='-1,2,3,4', test=True) 

El doble tablero detiene argparse buscando más interruptores opcionales; es la manera estándar de facto de manejar exactamente este caso de uso para herramientas de línea de comandos.

De la documentación :

El método parse_args () intenta dar errores siempre que el usuario ha cometido un error claramente, pero algunas situaciones son intrínsecamente ambiguas. Por ejemplo, el argumento de línea de comando -1 podría ser un bash de especificar una opción o un bash de proporcionar un argumento posicional. El método parse_args () es cauteloso aquí: los argumentos de posición solo pueden comenzar con – si parecen números negativos y no hay opciones en el analizador que parezcan números negativos:

Como -1,2,3,4 no parece un número negativo, debe “escapar” con el -- como en la mayoría de los sistemas * nix.

Otra solución sería usar nargs para la posición y pasar los números como espacios separados:

 #test.py import argparse parser = argparse.ArgumentParser() parser.add_argument('positional', nargs='*') #'+' for one or more numbers print parser.parse_args() 

Salida:

 $ python test.py -1 2 3 -4 5 6 Namespace(positional=['-1', '2', '3', '-4', '5', '6']) 

Una tercera forma de obtener lo que desea es usar parse_known_args lugar de parse_args . No agrega el argumento posicional al analizador y lo analiza manualmente en su lugar:

 import argparse parser = argparse.ArgumentParser() parser.add_argument('--test', action='store_true') parsed, args = parser.parse_known_args() print parsed print args 

Resultado:

 $ python test.py --test -1,2,3,4 Namespace(test=True) ['-1,2,3,4'] 

Esto tiene la desventaja de que el texto de ayuda será menos informativo.