Python-Abhängigkeiten zwischen den Gruppen mit argparse
Begann ich zu lernen, Python, und jetzt Lerne ich die großen Vorteile der argparse
.
Mit argparse
habe ich zwei Gruppen von Argumenten: group_list
und group_simulate
. Jede der Gruppen hat Ihre eigenen Argumente-der Benutzer kann angeben, nur ein argument in jeder Gruppe (erreicht mit parser.add_mutually_exclusive_group()
).
Und jetzt ist mein Ziel nicht vorhanden ist, kann ein syntax-Fehler, wenn der Benutzer die angegebenen Argumente von beiden groupgs und nicht von nur einer von Ihnen-und das möchte ich erreichen dies, indem mithilfe der Funktionen von argparse
und nicht durch schreiben eine Methode, die fragt, ob dies und das angegeben wurde, drucken syntax-Fehler.
import argparse
parser = argparse.ArgumentParser(
description='this is the description',
epilog="This is the epilog",
argument_default=argparse.SUPPRESS
)
parser.add_argument('-v', '--verbose', help='verbose', action='store_true', default=False)
group_list = parser.add_mutually_exclusive_group()
group_list.add_argument('-m', help='list only modules', action='store_const', dest='list', const='modules', default='all')
group_list.add_argument('-p', help='list only ports', action='store_const', dest='list', const='ports', default='all')
group_list.add_argument('--list', help='list only module or ports', choices=['modules','ports'], metavar='<modules/ports>', default='all')
group_simulate = parser.add_mutually_exclusive_group()
group_simulate.add_argument('-M', help='simulate module down', nargs=1, metavar='module_name', dest='simulate')
group_simulate.add_argument('-P', help='simulate FC port down', nargs=1, metavar='fc_port_name', dest='simulate')
group_simulate.add_argument('-I', help='simulate iSCSI port down', nargs=1, metavar='iSCSI_port_name', dest='simulate')
group_simulate.add_argument('--simulate', help='simulate module or port down', nargs=1, dest='simulate')
args = parser.parse_args()
print args
So reden, genauer gesagt:
erlaubt:
test.py
output: Namespace(list='all', verbose=False)
test.py -m
output: Namespace(list='modules', verbose=False)
test.py -P asfasf
output: Namespace(P=['asfasf'], list='all', verbose=False)
nicht erlaubt:
test.py -m -P asfsaf
expected output: <the help message>
test.py -P asfasf -m
expected output: <the help message>
Habe ich versucht zu erreichen, wollte den Gegner mit der option add_subparsers
aus argparse
aber ohne Erfolg.
Also meine Frage ist wie erreichen Sie diese situation?
- was ist dann der Unterschied zu werfen, sich gegenseitig ausschließende Argumente in einer Gruppe?
- Die Verwendung von mehreren sich gegenseitig ausschließenden Gruppen können Sie, zum Beispiel, vorbei an der
required
argument, um nur einige von Ihnen. Dass ein sich gegenseitig ausschließendes Gruppe können Sie nicht tun. Ein anderer Vorteil ist, dass die Hilfe, die Meldung ist ein wenig informativer, wenn Sie mehr als ein sich gegenseitig ausschließendes Gruppe. Auch in der Zukunft einige weitere Informationen über die sich gegenseitig ausschließenden Gruppe zur Verfügung gestellt werden könnten(z.B. Titel und Beschreibung), und somit wäre es mehr informative Hilfe-Nachrichten. - aber wenn man in der Gruppe ist
required
um eine arg, tut das nicht sofort ausschließen, alle anderen Gruppen? - Ich würde Zustimmen, das wenn ein argument ist definiert als
required
werden, wird dies in Konflikt mit deradd_mutually_exclusive
- da Sie haben Sie dieses argument angeben und nicht in der Lage zu spezifizieren, mit anderen Argumenten, ist dies, wie ich es verstehe. im obigen Fall hatte ich keinerequired
Argumente. - Ich weiß nicht, warum diese Antwort wurde akzeptiert. Die OP besagt, dass Sie sollten in der Lage sein zu wählen, genau 1
-m, -p, --list
UND genau 1-M, -P, -I, --simulate
. Diese Antwort macht das nicht. - Außerdem, ich weiß nicht, was der Punkt, der
--list
und--simulate
allein sein könnte. Es scheint, dass das, was Sie EIGENTLICH wollen, ist entweder--list
mit einem-m, -p
oder--simulate
mit einem-M, -P, -I
. Dies ist, warum Sie sollten beginnen immer mit dem schreiben eine sinnvolle Nutzung-Anweisung zuerst. Bekommen es direkt in Ihrem Kopf und "auf dem Papier" zunächst. Anschließend können Sie code, oder zu kommunizieren, um Hilfe zu bekommen. Wenn Sie nicht schreiben können eine Verwendung der Aussage für es Sie entweder nicht wissen, POSIX, oder Sie haben eine schlechte Idee, alle zusammen. - Ich weiß nicht, es ist für Lernzwecke oder nicht, aber dieses problem Spezifikation ist viel komplizierter, als es sein muss. Es ist einfach auf der Suche nach set 2 Attribute
list
undsimulate
.list
kann eine Auswahl von 3 Dingen;simulate
ist eine beliebige Zeichenfolge, trotz der Tatsache, dass es 4 mögliche flags.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Können Sie eine gemeinsame sich gegenseitig ausschließen-Gruppe als "root" den zwei Untergruppen:
Ergebnis:
group_simulate
es wird Hinzugefügtroot_group
als gut. Es ist auch Hinzugefügt, umparser
und seineoptional arguments
Gruppe. Der Netto-Effekt ist, dass alle 7 Aktionen schließen sich gegenseitig aus. Auch dieusage
code nicht verarbeiten verschachtelte Gruppen. Hinweis: die[[
und der Mangel an|
zwischen den verschachtelten Gruppen.group_simulate
hat einecontainer
Attribut, das auf dieroot_group
,root_group
nicht über eine Liste seiner verschachtelten Gruppen. Es ist ein_mutually_exclusive_groups
Attribut, aber dieses geteilt wird (gleiche Referenz) unter den parser und alle Gruppen, die (ausschließlich oder nicht). bugs.python.org/issue10984 hat einen patch mit einem formatter, die angezeigt werden können überlappende exklusive Gruppen -, es zeigt aber, jede Gruppe einzeln, nicht verschachtelt.Verwenden Docopt! Sie sollten sich nicht zu schreiben, dass eine Nutzung doc und dann stundenlang versucht herauszufinden, wie man argparse zu erstellen es für Sie. Wenn Sie wissen, POSIX-Sie wissen, wie zu interpretieren, dass eine Nutzung doc, weil es ein standard ist. Docopt wissen, wie zu interpretieren die Nutzung docs, die dasselbe wie Sie tun. Wir brauchen eine Abstraktions-Schicht.
Ich denke, dass die OP fehlgeschlagen ist, zu beschreiben, Ihre eigenen Absichten, basierend auf dem, was ich lese in Ihren Hilfe-text. Ich werde versuchen zu spekulieren, was Sie zu tun versuchen.
test.py
Zwar wäre es möglich zu kommunizieren, die alle von der Nutzung in einer einzigen Zeile, mit der komplexe, verschachtelte Bedingungen, das ist mehr lesbar. Dies ist der Grund, warum docopt macht so viel Sinn. Für ein CLI-Programm, das Sie wollen sicherstellen, dass Sie kommunizieren, um den Benutzer eindeutig. Warum lernen einige obskure Modul syntax, in der Hoffnung, dass Sie davon überzeugen kann, es zu schaffen, die die Kommunikation mit dem Benutzer für Sie? Nehmen Sie sich die Zeit, den Blick auf andere POSIX-tools mit der option Regeln sind ähnlich, um Ihre Bedürfnisse und copy-pasta.
docopt
Verkaufsgespräche so weit.argp
mit mehreren unabhängigen Parser (jeder Benutzung Zeile behandelt, von einem anderen parser)? Python verfügt bereits über einen parser basierend aufgetopt
, die viel einfacher ist.argp
? Was könnte einfacher sein als das schreiben genaue Benutzer-Nachricht, die Sie wollen gezeigt und es wird direkt interpretiert?POSIX
argument handling war genug, um zu schreiben eine gutedocopt
Nutzung. Eine Suche nach 'posix Argumente führen mich zu einem GNU-C-Bibliothek, die hat 2 Parser,getopt
undargp
, gnu.org/software/libc/manual/html_node/Argp.htmlxor
( | )
syntax. Das sieht aus wie eindocopt
Erweiterung, nicht reinPOSIX
.Eine einfachere version von diesem parser ist
Mit dabei helfen, dass sieht aus wie:
Neben
verbose
(hier habe ich ersetztcount
) die OP-sets an Attributelist
undsimulate
.list
hat einen Standardwert vonall
eingestellt werden können, ummodules
oderports
.-m
und-p
sind nur kurze Schnitte, und don ' T wirklich hinzufügen, um die definition. Verknüpfungen sind nützlich, wenn die Definition eine Menge von Optionen, vor allem, wenn Sie die Optionen zusammen verwendet werden können (z.B.-vpm
). Aber hier nur eine option zulässig ist (neben-v
).simulate
nimmt eine unbegrenzte Zeichenfolge. DieM/P/C
Optionen sind nur Dokumentation Bequemlichkeiten, und nicht beschränken Sie die Werte, oder fügen Bedeutung.Dies ist eine nette übung in die Grenzen der
argparse
(oder alle anderen parser), aber ich denke, es ist zu kompliziert, um nützlich zu sein. Trotz all der Gruppierungen kommt es zu so dass nur eine option.==========================
Kommentare über
docopt
undPOSIX
argument handling aufgefordert, mich zu sehen C argument Bibliotheken.getopt
ist der alte standard. Python hat ein funktionales äquivalent, https://docs.python.org/2/library/getopt.htmlAnderen parser in GNU library ist
argp
.http://www.gnu.org/software/libc/manual/html_node/Argp.html
Habe ich noch nicht gesehen, noch eine klare Beschreibung, was es ergänzt die
getopt
syntax. Aber der folgende Absatz ist interessant.Es klingt ein bisschen wie die
argparse
subparser Mechanismus. Das heißt, es gibt eine Art meta-parser delegieren kann die Aktion zu einer (oder mehr) subparsers. Aber inargparse
subparsers müssen explizit benannt werden, durch den Benutzer.Eine mögliche Erweiterung ist die meta-parser den Kontext sehen. Zum Beispiel im OP-Fall, wenn es sieht, jeder der [--list, -p, -m], verwenden Sie die
list
subparser, wenn eine dersimulate
Argumente, Verwendung diesimulate
subparser. Möglicherweise geben einige weitere mächtige Gruppierung-tools. Und könnte es möglich sein, zu realisieren, dass etwas mit dem Lagerargparse
. Sie können erstellen und ausführen von verschiedenenparsers
auf der gleichensys.argv
.