Python argparse ignore les arguments non reconnus

206

Optparse, l'ancienne version ignore simplement tous les arguments non reconnus et continue. Dans la plupart des situations, ce n'est pas idéal et a été changé dans argparse. Mais il y a quelques situations où vous souhaitez ignorer tous les arguments non reconnus et analyser ceux que vous avez spécifiés.

Par exemple:

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

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

Y a-t-il un moyen de remplacer cela?

joedborg
la source
14
Très pratique si vous écrivez un wrapper dans un autre programme et que vous souhaitez capturer et modifier quelques arguments, mais passez le reste!
Alan De Smet
2
Exactement pourquoi je me suis retrouvé ici @AlanDeSmet! Heureux que je
n'essaye

Réponses:

351

Remplacer

args = parser.parse_args()

avec

args, unknown = parser.parse_known_args()

Par exemple,

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
la source
21
+1 - ne savait pas qu'il y avait quelque chose commeparse_known_args
avasal
7
Moi non plus! Je l'ai même manqué dans les documents docs.python.org/library/… . Merci
joedborg
1
Cela est apparu lorsque j'essayais d'utiliser nosetest avec des parseargs (il refusait d'autoriser l'utilisation des arguments nosetest) parce que je le faisais parser.parse_args(None)plutôt que parser.parse_args([])dans mes tests.
Andy Hayden du
3
FWIW, utiliser parse_known_argsplutôt qu'autoriser parse_argsl'utilisation de ArgumentParsercode dans le cadre de if __name__ == 'main':(une condition qui Trueconcerne toutes les cellules d'un bloc-notes IPython ... que je trouve très utile pour le développement et le test du code que je souhaite éventuellement migrer vers un script appelé à partir d'une ligne de commande)
gumption
1
Cela ne semble pas fonctionner avec des arguments optionnels "connus" qui ne sont pas transmis.
Sharud
21

Vous pouvez mettre les parties restantes dans un nouvel argument parser.add_argument('args', nargs=argparse.REMAINDER)si vous souhaitez les utiliser.

lichenbo
la source
1
Cela fonctionne avec parse_args()et ne nécessite pas parse_known_args()(sur Python 2.7).
OozeMeister
4
L'utilisation d'argparse.REMAINDER semble être lourde de bogues de longue date. Je ne peux certainement pas le faire fonctionner. parse_known_args () est une bonne alternative.
Matt
1
Je viens de rencontrer un bug REMAINDER de longue date aujourd'hui: bugs.python.org/issue17050
Scott Carpenter
7

En fait, argparse "ignore" toujours _unrecognized_args. Tant que ces arguments "non reconnus" n'utilisent pas le préfixe par défaut vous n'entendrez aucune plainte de l'analyseur.

En utilisant la configuration de @ anutbu mais avec la norme parse.parse_args(), si nous devions exécuter notre programme avec les arguments suivants.

$ program --foo BAR a b +cd e

Nous aurons cette collection de données à espace de noms avec laquelle travailler.

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

Si nous voulions que le préfixe par défaut soit -ignoré, nous pourrions changer le ArgumentParser et décider que nous allons utiliser un +pour nos arguments "reconnus" à la place.

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

La même commande produira

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

Mettez ça dans votre pipe et fumez-le =)

nJoy!

nickl-
la source