El argumento de Python ignora los argumentos no reconocidos

206

Optparse, la versión anterior simplemente ignora todos los argumentos no reconocidos y continúa. En la mayoría de las situaciones, esto no es ideal y se cambió en argparse. Pero hay algunas situaciones en las que desea ignorar cualquier argumento no reconocido y analizar los que ha especificado.

Por ejemplo:

parser = argparse.ArgumentParser()
parser.add_argument('--foo', dest="foo")
parser.parse_args()

$python myscript.py --foo 1 --bar 2
error: unrecognized arguments: --bar

¿Hay alguna forma de sobrescribir esto?

joedborg
fuente
14
Muy útil si está escribiendo un contenedor para otro programa, y ​​desea capturar y modificar algunos argumentos, ¡pero pase el resto!
Alan De Smet
2
¡Exactamente por qué terminé aquí @AlanDeSmet! Me alegro de no estar tratando de hacer algo loco :)
dwanderson

Respuestas:

351

Reemplazar

args = parser.parse_args()

con

args, unknown = parser.parse_known_args()

Por ejemplo,

import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--foo')
args, unknown = parser.parse_known_args(['--foo', 'BAR', 'spam'])
print(args)
# Namespace(foo='BAR')
print(unknown)
# ['spam']
unutbu
fuente
21
+1 - no sabía que había algo asíparse_known_args
avasal
77
Yo tampoco! Incluso me lo perdí en los documentos docs.python.org/library/… . Gracias
joedborg
1
Esto surgió cuando traté de usar la prueba nasal con parseargs (se negó a permitir que se usaran los arcos de prueba nasal), la razón fue porque estaba haciendo en parser.parse_args(None)lugar de parser.parse_args([])en mis pruebas.
Andy Hayden
3
FWIW, usar en parse_known_argslugar de parse_argshabilitar el uso del ArgumentParsercódigo dentro del alcance de if __name__ == 'main':(una condición que es Truepara todas las celdas en un Cuaderno IPython ... que encuentro ayuda mucho al código de desarrollo y prueba que quiero migrar eventualmente a un script invocado desde una línea de comando)
gumption
1
Esto no parece funcionar con argumentos opcionales que son "conocidos" que no se pasan.
Sharud
21

Puede colocar las partes restantes en un nuevo argumento con parser.add_argument('args', nargs=argparse.REMAINDER)si desea usarlas.

lichenbo
fuente
1
Esto funciona con parse_args()y no requiere parse_known_args()(en Python 2.7).
OozeMeister
44
El uso de argparse.REMAINDER parece estar plagado de errores de larga data. Ciertamente no puedo hacer que funcione. parse_known_args () es una buena alternativa.
Matt
1
Hoy me
Scott Carpenter
7

En realidad, argparse todavía "ignora" _unrecognized_args. Mientras estos argumentos "no reconocidos" no usen el prefijo predeterminado , no escuchará ninguna queja del analizador.

Usando la configuración de @ anutbu pero con el estándar parse.parse_args(), si tuviéramos que ejecutar nuestro programa con los siguientes argumentos.

$ program --foo BAR a b +cd e

Tendremos esta recopilación de datos de espacio de nombres para trabajar.

Namespace(_unrecognized_args=['a', 'b', '+cd', 'e'], foo='BAR')

Si quisiéramos -ignorar el prefijo predeterminado , podríamos cambiar el ArgumentParser y decidir que vamos a utilizar a +para nuestros argumentos "reconocidos".

parser = argparse.ArgumentParser(prefix_chars='+')
parser.add_argument('+cd')

El mismo comando producirá

Namespace(_unrecognized_args=['--foo', 'BAR', 'a', 'b'], cd='e')

Pon eso en tu pipa y fúmalo =)

nJoy!

nickl-
fuente