Python-Argumente ignorieren nicht erkannte Argumente

206

Optparse, die alte Version ignoriert einfach alle nicht erkannten Argumente und fährt fort. In den meisten Situationen ist dies nicht ideal und wurde in Argparse geändert. Es gibt jedoch einige Situationen, in denen Sie nicht erkannte Argumente ignorieren und die von Ihnen angegebenen Argumente analysieren möchten.

Beispielsweise:

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

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

Gibt es sowieso etwas zu überschreiben?

joedborg
quelle
14
Sehr praktisch, wenn Sie einen Wrapper in ein anderes Programm schreiben und einige Argumente erfassen und ändern möchten, aber den Rest weitergeben möchten!
Alan De Smet
2
Genau deshalb bin ich hier gelandet @AlanDeSmet! Ich bin froh, dass ich nicht versuche, etwas Verrücktes zu tun :)
dwanderson

Antworten:

350

Ersetzen

args = parser.parse_args()

mit

args, unknown = parser.parse_known_args()

Beispielsweise,

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
quelle
21
+1 - wusste nicht, dass es so etwas wieparse_known_args
avasal
7
Weder habe ich! Ich habe es sogar in den Dokumenten docs.python.org/library/… verpasst . Vielen Dank
Joedborg
1
Dies trat auf, als ich versuchte, Nosetest mit Parseargs zu verwenden (es verweigerte die Verwendung von Nosetest-Argumenten). Der Grund dafür war, dass ich dies parser.parse_args(None)eher als parser.parse_args([])in meinen Tests tat .
Andy Hayden
3
FWIW verwendet die Verwendung von In-Code im Rahmen von (eine Bedingung, die für alle Zellen in einem IPython-Notizbuch gilt), parse_known_argsanstatt sie zu aktivieren. Ich finde, dass dies den Entwicklungs- und Testcode, den ich eventuell in ein aufgerufenes Skript migrieren möchte, erheblich unterstützt von einer Kommandozeile)parse_argsArgumentParserif __name__ == 'main':True
Kaugummi
1
Dies scheint nicht mit optionalen Argumenten zu funktionieren, von denen "bekannt" ist, dass sie nicht übergeben werden.
Sharud
21

Sie können die verbleibenden Teile in ein neues Argument einfügen, parser.add_argument('args', nargs=argparse.REMAINDER)wenn Sie sie verwenden möchten.

Lichenbo
quelle
1
Dies funktioniert mit parse_args()und erfordert nicht parse_known_args()(unter Python 2.7).
OozeMeister
4
Die Verwendung von argparse.REMAINDER scheint mit langjährigen Fehlern behaftet zu sein. Ich kann es sicher nicht zum Laufen bringen. parse_known_args () ist eine gute Alternative.
Matt
1
Ich bin heute auf einen langjährigen REMAINDER-Fehler gestoßen: bugs.python.org/issue17050
Scott Carpenter
7

Eigentlich "ignoriert" Argparse immer noch _unrecognized_args. Solange diese "nicht erkannten" Argumente nicht das Standardpräfix verwenden, werden Sie keine Beschwerden vom Parser hören.

Verwenden Sie die Konfiguration von @ anutbu, jedoch mit dem Standard parse.parse_args(), wenn Sie unser Programm mit den folgenden Argumenten ausführen möchten .

$ program --foo BAR a b +cd e

Wir werden diese Namespaced-Datenerfassung haben, mit der wir arbeiten können.

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

Wenn wir wollten, dass das Standardpräfix -ignoriert wird, können wir den ArgumentParser ändern und entscheiden, dass wir +stattdessen ein für unsere "erkannten" Argumente verwenden.

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

Der gleiche Befehl wird erzeugt

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

Steck das in deine Pfeife und rauche es =)

nJoy!

Nickl-
quelle