Deaktivieren / Entfernen von Argument in argparse

Ist es möglich, ein Argument in argparse zu entfernen oder zu deaktivieren, so dass es in der Hilfe nicht angezeigt wird? Wie?

Es ist leicht, neue Argumente hinzuzufügen:

parser = argparse.ArgumentParser() parser.add_argument('--arg1', help='Argument 1') parser.add_argument('--arg2', help='A second one') 

Und ich weiß, dass Sie Argumente mit einer neuen Definition überschreiben können, indem Sie den "Resolve" -Konflikt-Handler angeben:

 #In one script that should stand-alone and include arg1: parser = argparse.ArgumentParser(conflict_handler='resolve') parser.add_argument('--arg1', help='Argument 1') parser.add_argument('--arg2', help='A second one') #In another script with similar options parser.add_argument('--arg1', help='New number 1') 

Aber das beinhaltet noch arg1 in der Hilfe-Nachricht und die Ergebnisse von parse_args Gibt es so etwas wie

 #Wishful thinking #In another script with similar options, that shouldn't include arg1 parser.remove_argument('--arg1') 

Oder eine andere vernünftig einfache Möglichkeit, dies zu erreichen?

Auch: Wäre der Ansatz anders, wenn das Argument ein Positionsargument wäre?

Hinweis: Das Problem mit dem Entfernen von arg1 nach dem Parsing, wie hier vorgeschlagen , ist, dass das Argument immer noch in der Hilfe zeigt

3 Solutions collect form web for “Deaktivieren / Entfernen von Argument in argparse”

Trotz der Fehlerfrage, die ich unten erwähne, schlägt Ihr Gebrauch von resolve eine mögliche Methode vor. Dies ist nicht für den Anfänger oder jemanden, der mit der öffentlichen API bleiben muss.

Der parser hat eine Liste der Action- (Argument-) Objekte (wie von add_argument ).

Mit der 2. Parser-Definition ist die Liste _actions :

 In [22]: parser._actions Out[22]: [_HelpAction(option_strings=['-h', '--help'], dest='help'...), _StoreAction(option_strings=['--arg2'], dest='arg2', nargs=None, const=None, default=None, type=None, choices=None, help='A second one', metavar=None), _StoreAction(option_strings=['--arg1'], dest='arg1', nargs=None, const=None, default=None, type=None, choices=None, help='New number 1', metavar=None)] 

Wenn du einen Konflikt mit resolve hinzufügst, entfernt es die vorhandene Aktion, die in Konflikt steht. Schauen Sie sich die _handle_conflict_resolve Methode für Details an. Aber ich kann es davor töten, eine Aktion zu entfernen, ohne eine neue hinzuzufügen.

 In [23]: parser._handle_conflict_resolve(None, [('--arg1',parser._actions[2])]) 

Betrachten Sie _actions und helfen Sie zu überprüfen, dass --arg1 ist weg.

 In [24]: parser._actions Out[24]: [_HelpAction(option_strings=['-h', '--help'], dest='help',....), _StoreAction(option_strings=['--arg2'], dest='arg2', nargs=None,...)] In [25]: parser.print_help() usage: ipython3 [-h] [--arg2 ARG2] optional arguments: -h, --help show this help message and exit --arg2 ARG2 A second one 

resolve nur Handles- optionals , diejenigen, wo die Flaggen-Strings in Konflikt stehen könnten. Und es entfernt zuerst widersprüchliche Flaggen, indem sie die widersprüchliche Handlung nur entfernen, wenn keine Flaggen übrig bleiben. Sei besonders vorsichtig, wenn du kurze und lange Optionen hast.

Und das geht nicht auf den Fall der Positionals. Sie haben keine Fahnen, und sie können die Parameter teilen. (Obwohl nur einer im Ergebnis erscheinen wird, es sei denn, sie sind Anhänge).

 In [27]: foo1 = parser.add_argument('foo',help='foo 1 positional') In [28]: foo2 = parser.add_argument('foo',help='foo 2 positional') In [29]: parser.print_help() usage: ipython3 [-h] [--arg2 ARG2] foo foo positional arguments: foo foo 1 positional foo foo 2 positional ... 

Um ein bisschen mehr herumzusehen, sieht es so aus, als könne ich eine dieser neuen Positionen entfernen:

 In [33]: parser._actions[-1] Out[33]: _StoreAction(option_strings=[], dest='foo',... help='foo 2 positional', metavar=None) In [35]: foo2=parser._actions[-1] In [36]: foo2.container._remove_action(foo2) In [39]: parser.print_help() usage: ipython3 [-h] [--arg2 ARG2] foo positional arguments: foo foo 1 positional .... 

Wenn ich _actions[-2] hätte, hätte ich den ersten foo . Wenn ich den Wert add_argument , den add_argument zu einer Variablen zurückgibt, zB foo1 , kann ich das verwenden, anstatt den Wert in der Liste parser._actions . Es kann hilfreich sein, einen Beispielparser in einer internen Shell auszuführen (ich verwende IPython) und schaue diese Objekte an.

Wieder scheint dies an einem einfachen Beispiel zu arbeiten, aber es braucht sorgfältige Tests, wenn es mit etwas komplexer (oder für die Produktion) verwendet wird.


Das Thema wurde vor ein paar Jahren auf die Python-Bugs / Issues erhoben:

Add remove_argument() method to argparse.ArgumentParser

Ich besprach die Schwierigkeiten bei der vollständigen Entfernung und schlug einige Alternativen vor. argparse.SUPPRESS kann verwendet werden, um sich zu verstecken. optionals können ignoriert werden, wenn sie nicht benötigt werden. positionals sind schwieriger, obwohl ich vorgeschlagen, Tweaking ihre Attribute ( nargs und default ). Aber es ist schon eine Weile her, also muss ich diese Beiträge überprüfen.

==================================

Ich war neugierig auf @2rs2ts Problem (siehe Kommentar).

Ich machte einen Parser und benutzte ihn dann als Elternteil zu einem anderen Parser (keine Notwendigkeit, den Subparser-Mechanismus zu benutzen). Dann habe ich ein Argument von einem Parser entfernt und sah die Veränderungen im anderen Parser an.

Machen Sie einen Elternparser mit einem Argument:

 In [59]: p=argparse.ArgumentParser() In [60]: p.add_argument('--foo') Out[60]: _StoreAction(option_strings=['--foo'], dest='foo', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None) 

Machen Sie ein anderes mit den parents :

 In [61]: p1=argparse.ArgumentParser(parents=[p],add_help=False) In [62]: p1._actions Out[62]: [_HelpAction(option_strings=['-h', '--help'], dest='help', nargs=0, const=None, default='==SUPPRESS==', type=None, choices=None, help='show this help message and exit', metavar=None), _StoreAction(option_strings=['--foo'], dest='foo', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)] 

Beachten Sie, dass die 2. Aktion für beide Parser gleich ist (gleiche ID). parents nur einen Verweis auf das Original kopiert --foo Action, es hat keine Kopie gemacht.

 In [63]: id(p._actions[1]) Out[63]: 3000108652 In [64]: id(p1._actions[1]) Out[64]: 3000108652 

Jetzt entfernen '–foo' von einem Parser, mit dem Trick habe ich vorher gearbeitet:

 In [65]: p1._handle_conflict_resolve(None,[('--foo',p1._actions[1])]) In [66]: p1._actions Out[66]: [_HelpAction(option_strings=['-h', '--help'], dest='help', nargs=0, const=None, default='==SUPPRESS==', type=None, choices=None, help='show this help message and exit', metavar=None)] 

'–foo' ist aus der p1 Liste gegangen, aber immer noch in der p Liste vorhanden. Aber option_strings ist jetzt leer.

 In [67]: p._actions Out[67]: [_HelpAction(option_strings=['-h', '--help'], dest='help', nargs=0, const=None, default='==SUPPRESS==', type=None, choices=None, help='show this help message and exit', metavar=None), _StoreAction(option_strings=[], dest='foo', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)] 

Der resolve Code entfernte sich widersprüchliche option_strings aus der --foo Aktion und entfernte sie dann aus der p1._actions Liste. Aber das Ändern von option_strings für die p1 Referenz hat auch die p Referenz geändert.

argparse verwendet ein paar Möglichkeiten, um positionals von optionals zu unterscheiden, aber die am häufigsten beim Parsing verwendete ist, zu betrachten, ob das option_strings Attribut leer ist oder nicht. Durch das Entleeren dieses Attributs, hat sich die resolve effektiv in eine positional .

Oops, mein Gedächtnis ist nicht das, was es sein sollte. 🙂 Vor einem Jahr habe ich eine ähnliche Frage mit parents beantwortet und resolve

https://stackoverflow.com/a/25821043/901925 argparse conflict resolver for options in subcommands turns keyword argument into positional argument

Ist es möglich, ein Argument in argparse zu entfernen oder zu deaktivieren, so dass es in der Hilfe nicht angezeigt wird?

Setzen Sie help zu argparse.SUPPRESS wenn Sie das Argument hinzufügen, wie argparse.SUPPRESS :

 parser.add_argument('--arg1', help=argparse.SUPPRESS) 

Dadurch wird verhindert, dass das Argument in der Standard-Hilfe-Ausgabe angezeigt wird.

Funktion zum Entfernen von argparse-Optionen:

 def remove_options(parser, options): for option in options: for action in parser._actions: if vars(action)['option_strings'][0] == option: parser._handle_conflict_resolve(None,[(option,action)]) break 
  • __init__ und Argumente in Python
  • Python: Was ist der Unterschied zwischen Call-by-Value und Call-by-Object?
  • Beste Weg, um Funktionsargumente in Python zu überprüfen
  • Python: Argumentbasiertes Singleton
  • Gute Verwendungen für veränderbare Funktionsargument-Standardwerte?
  • Generiere eine Liste von Argumenten in ordnungsgemäßer Reihenfolge von args und kwargs?
  • Python: subprocess und läuft ein bash-Skript mit mehreren Argumenten
  • Python-Passing-Wörterbuch zu verarbeiten in Multiprocessing
  • Python: Übergeben von Parametern mit Namen zusammen mit kwargs
  • Python-Fehler: "ValueError: benötigt mehr als 1 Wert zum Entpacken"
  • Vermeiden Sie es, alle Argumente in einer Unterklasse anzugeben
  • Python ist die beste Programmiersprache der Welt.