optparse — Parser für Kommandozeilenoptionen¶
Quellcode: Lib/optparse.py
Auswahl einer Bibliothek zur Argumentenanalyse¶
Die Standardbibliothek enthält drei Bibliotheken zur Argumentenanalyse
getopt: ein Modul, das eng an die prozedurale CgetoptAPI angelehnt ist. Seit vor der ersten Python 1.0-Version in der Standardbibliothek enthalten.optparse: ein deklarativer Ersatz fürgetopt, der eine äquivalente Funktionalität bietet, ohne dass jede Anwendung ihre eigene prozedurale Logik zur Optionsanalyse implementieren muss. Seit der Python 2.3-Version in der Standardbibliothek enthalten.argparse: eine meinungsstärkere Alternative zuoptparse, die standardmäßig mehr Funktionalität bietet, allerdings auf Kosten einer geringeren Flexibilität der Anwendung bei der genauen Kontrolle, wie Argumente verarbeitet werden. Seit den Python 2.7- und Python 3.2-Versionen in der Standardbibliothek enthalten.
Wenn keine spezifischeren Designbeschränkungen für die Argumentenanalyse vorliegen, ist argparse die empfohlene Wahl für die Implementierung von Kommandozeilenanwendungen, da es das höchste Maß an Basisfunktionalität mit dem geringsten Anwendungsaufwand bietet.
getopt wird fast ausschließlich aus Gründen der Abwärtskompatibilität beibehalten. Es dient jedoch auch einem Nischenanwendungsfall als Werkzeug für die Prototypenentwicklung und das Testen der Kommandozeilenargumentenverarbeitung in getopt-basierten C-Anwendungen.
optparse sollte als Alternative zu argparse in folgenden Fällen in Betracht gezogen werden
eine Anwendung verwendet bereits
optparseund möchte keine subtilen Verhaltensänderungen riskieren, die bei der Migration zuargparseauftreten könnendie Anwendung erfordert zusätzliche Kontrolle über die Art und Weise, wie Optionen und Positionsargumente auf der Kommandozeile verschachtelt werden (einschließlich der Möglichkeit, die Verschachtelungsfunktion vollständig zu deaktivieren)
die Anwendung erfordert zusätzliche Kontrolle über die inkrementelle Verarbeitung von Kommandozeilenelementen (obwohl
argparsedies unterstützt, ist die genaue Funktionsweise in der Praxis für einige Anwendungsfälle unerwünscht)die Anwendung erfordert zusätzliche Kontrolle über die Verarbeitung von Optionen, die Wertargumente akzeptieren, welche mit
-beginnen können (wie delegierte Optionen, die an aufzurufende Unterprozesse übergeben werden sollen)die Anwendung erfordert ein anderes Kommandozeilenparameter-Verarbeitungsverhalten, das
argparsenicht unterstützt, aber das sich mithilfe der vonoptparseangebotenen Low-Level-Schnittstelle implementieren lässt
Diese Überlegungen bedeuten auch, dass optparse wahrscheinlich eine bessere Grundlage für Bibliotheksautoren bietet, die externe Bibliotheken zur Verarbeitung von Kommandozeilenargumenten schreiben.
Betrachten wir als konkretes Beispiel die folgenden beiden Konfigurationen zur Verarbeitung von Kommandozeilenargumenten, die erste mit optparse und die zweite mit argparse
import optparse
if __name__ == '__main__':
parser = optparse.OptionParser()
parser.add_option('-o', '--output')
parser.add_option('-v', dest='verbose', action='store_true')
opts, args = parser.parse_args()
process(args, output=opts.output, verbose=opts.verbose)
import argparse
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('-o', '--output')
parser.add_argument('-v', dest='verbose', action='store_true')
parser.add_argument('rest', nargs='*')
args = parser.parse_args()
process(args.rest, output=args.output, verbose=args.verbose)
Der offensichtlichste Unterschied besteht darin, dass bei der optparse-Version die Nicht-Option-Argumente nach Abschluss der Optionsverarbeitung separat von der Anwendung verarbeitet werden. In der argparse-Version werden Positionsargumente auf die gleiche Weise deklariert und verarbeitet wie benannte Optionen.
Die argparse-Version verarbeitet jedoch einige Parameterkombinationen anders als die optparse-Version. Zum Beispiel (neben anderen Unterschieden)
die Angabe von
-o -vergibtoutput="-v"undverbose=Falsebei Verwendung vonoptparse, aber einen Nutzungsfehler beiargparse(der beanstandet, dass kein Wert für-o/--outputangegeben wurde, da-vals Verbositätsflag interpretiert wird)ähnlich ergibt die Angabe von
-o --output="--"undargs=()bei Verwendung vonoptparse, aber einen Nutzungsfehler beiargparse(der ebenfalls beanstandet, dass kein Wert für-o/--outputangegeben wurde, da--als Beendigung der Optionsverarbeitung und Behandlung aller verbleibenden Werte als Positionsargumente interpretiert wird)die Angabe von
-o=fooergibtoutput="=foo"bei Verwendung vonoptparse, aberoutput="foo"mitargparse(da=als alternativer Trennzeichen für Optionswertargumente speziell behandelt wird)
Ob diese unterschiedlichen Verhaltensweisen in der argparse-Version als wünschenswert oder als Problem angesehen werden, hängt vom spezifischen Anwendungsfall der Kommandozeilenanwendung ab.
Siehe auch
click ist eine Drittanbieter-Bibliothek zur Verarbeitung von Argumenten (ursprünglich basierend auf optparse), die es ermöglicht, Kommandozeilenanwendungen als eine Reihe von dekorierten Befehlsimplementierungsfunktionen zu entwickeln.
Andere Drittanbieter-Bibliotheken, wie typer oder msgspec-click, ermöglichen die Angabe von Kommandozeilenschnittstellen auf eine Weise, die sich besser in die statische Prüfung von Python-Typ-Annotationen integriert.
Einleitung¶
optparse ist eine bequemere, flexiblere und leistungsfähigere Bibliothek zum Analysieren von Kommandozeilenoptionen als das minimalistische getopt-Modul. optparse verwendet einen eher deklarativen Stil der Kommandozeilenanalyse: Sie erstellen eine Instanz von OptionParser, füllen diese mit Optionen und analysieren die Kommandozeile. optparse ermöglicht es Benutzern, Optionen in der konventionellen GNU/POSIX-Syntax anzugeben und generiert zusätzlich Nutzungs- und Hilfemeldungen für Sie.
Hier ist ein Beispiel für die Verwendung von optparse in einem einfachen Skript
from optparse import OptionParser
...
parser = OptionParser()
parser.add_option("-f", "--file", dest="filename",
help="write report to FILE", metavar="FILE")
parser.add_option("-q", "--quiet",
action="store_false", dest="verbose", default=True,
help="don't print status messages to stdout")
(options, args) = parser.parse_args()
Mit diesen wenigen Codezeilen können Benutzer Ihres Skripts nun das „übliche Ding“ auf der Kommandozeile tun, zum Beispiel
<yourscript> --file=outfile -q
Beim Analysieren der Kommandozeile setzt optparse Attribute des von parse_args() zurückgegebenen options-Objekts basierend auf den vom Benutzer bereitgestellten Werten der Kommandozeile. Wenn parse_args() nach der Analyse dieser Kommandozeile zurückkehrt, ist options.filename "outfile" und options.verbose False. optparse unterstützt sowohl lange als auch kurze Optionen, erlaubt das Zusammenfassen von kurzen Optionen und die Zuordnung von Optionen zu ihren Argumenten auf verschiedene Weise. Daher sind die folgenden Kommandozeilen alle äquivalent zum obigen Beispiel
<yourscript> -f outfile --quiet
<yourscript> --quiet --file outfile
<yourscript> -q -foutfile
<yourscript> -qfoutfile
Zusätzlich können Benutzer eine der folgenden Optionen ausführen
<yourscript> -h
<yourscript> --help
und optparse gibt eine kurze Zusammenfassung der Optionen Ihres Skripts aus
Usage: <yourscript> [options]
Options:
-h, --help show this help message and exit
-f FILE, --file=FILE write report to FILE
-q, --quiet don't print status messages to stdout
wobei der Wert von yourscript zur Laufzeit ermittelt wird (normalerweise aus sys.argv[0]).
Hintergrund¶
optparse wurde explizit entwickelt, um die Erstellung von Programmen mit einfachen Kommandozeilenschnittstellen zu fördern, die den von der getopt()-Funktionsfamilie für C-Entwickler etablierten Konventionen folgen. Zu diesem Zweck unterstützt es nur die gebräuchlichsten Kommandozeilensyntaxen und -semantiken, die unter Unix üblich sind. Wenn Sie mit diesen Konventionen nicht vertraut sind, können Sie sich in diesem Abschnitt damit vertraut machen.
Terminologie¶
- Argument
ein auf der Kommandozeile eingegebener String, der von der Shell an
execl()oderexecv()übergeben wird. In Python sind Argumente Elemente vonsys.argv[1:](sys.argv[0]ist der Name des ausgeführten Programms). Unix-Shells verwenden auch den Begriff „Word“.Es ist gelegentlich wünschenswert, eine andere Argumentenliste als
sys.argv[1:]zu verwenden, daher sollten Sie „Argument“ als „ein Element vonsys.argv[1:]oder einer anderen Liste, die als Ersatz fürsys.argv[1:]bereitgestellt wird“ verstehen.- Option
ein Argument, das verwendet wird, um zusätzliche Informationen bereitzustellen, die die Ausführung eines Programms steuern oder anpassen. Es gibt viele verschiedene Syntaxen für Optionen; die traditionelle Unix-Syntax ist ein Bindestrich („-“) gefolgt von einem einzelnen Buchstaben, z. B.
-xoder-F. Außerdem erlaubt die traditionelle Unix-Syntax, mehrere Optionen zu einem einzigen Argument zusammenzufassen, z. B.-x -Fist äquivalent zu-xF. Das GNU-Projekt führte--gefolgt von einer Reihe von durch Bindestriche getrennten Wörtern ein, z. B.--fileoder--dry-run. Dies sind die einzigen beiden Optionssyntaxen, die vonoptparsebereitgestellt werden.Einige andere Optionssyntaxen, die die Welt gesehen hat, umfassen
ein Bindestrich gefolgt von einigen Buchstaben, z. B.
-pf(dies ist *nicht* dasselbe wie mehrere Optionen, die zu einem einzelnen Argument zusammengefasst sind)ein Bindestrich gefolgt von einem ganzen Wort, z. B.
-file(dies ist technisch äquivalent zur vorherigen Syntax, aber sie werden normalerweise nicht im selben Programm gesehen)ein Pluszeichen gefolgt von einem einzelnen Buchstaben, oder einigen Buchstaben, oder einem Wort, z. B.
+f,+rgbein Schrägstrich gefolgt von einem Buchstaben, oder einigen Buchstaben, oder einem Wort, z. B.
/f,/file
Diese Optionssyntaxen werden von
optparsenicht unterstützt, und das wird sich auch nie ändern. Dies ist beabsichtigt: Die ersten drei sind auf keiner Umgebung Standard, und die letzte ist nur sinnvoll, wenn Sie ausschließlich Windows oder bestimmte Legacy-Plattformen (z. B. VMS, MS-DOS) ansprechen.- Optionsargument
ein Argument, das auf eine Option folgt, eng mit dieser Option verbunden ist und aus der Argumentenliste konsumiert wird, wenn diese Option verarbeitet wird. Mit
optparsekönnen Optionsargumente entweder als separates Argument von ihrer Option vorliegen-f foo --file foo
oder im selben Argument enthalten sein
-ffoo --file=foo
Typischerweise nimmt eine gegebene Option entweder ein Argument auf oder nicht. Viele Leute wünschen sich eine Funktion für „optionale Optionsargumente“, was bedeutet, dass einige Optionen ein Argument nehmen, wenn sie es sehen, und keins, wenn sie es nicht tun. Dies ist einigermaßen umstritten, da es die Analyse mehrdeutig macht: Wenn
-aein optionales Argument nimmt und-beine andere Option ist, wie interpretieren wir dann-ab? Aufgrund dieser Mehrdeutigkeit unterstütztoptparsediese Funktion nicht.- positionsargument
etwas, das nach der Verarbeitung von Optionen in der Argumentenliste übrig bleibt, d. h. nachdem Optionen und ihre Argumente verarbeitet und aus der Argumentenliste entfernt wurden.
- erforderliche Option
eine Option, die auf der Kommandozeile angegeben werden muss; beachten Sie, dass der Ausdruck „erforderliche Option“ im Englischen widersprüchlich ist.
optparsehindert Sie nicht daran, erforderliche Optionen zu implementieren, unterstützt Sie dabei aber auch nicht wesentlich.
Betrachten Sie zum Beispiel diese hypothetische Kommandozeile
prog -v --report report.txt foo bar
-v und --report sind beides Optionen. Angenommen, --report nimmt ein Argument, dann ist report.txt ein Optionsargument. foo und bar sind Positionsargumente.
Wozu dienen Optionen?¶
Optionen werden verwendet, um zusätzliche Informationen bereitzustellen, um die Ausführung eines Programms zu optimieren oder anzupassen. Falls es nicht klar war, sind Optionen normalerweise *optional*. Ein Programm sollte in der Lage sein, auch ohne jegliche Optionen fehlerfrei zu laufen. (Wählen Sie ein beliebiges Programm aus den Unix- oder GNU-Toolsets. Kann es ohne Optionen ausgeführt werden und dennoch sinnvoll sein? Die Hauptausnahmen sind find, tar und dd – allesamt mutierte Unikate, die zu Recht für ihre nicht standardmäßige Syntax und verwirrenden Benutzeroberflächen kritisiert wurden.)
Viele Leute möchten, dass ihre Programme „erforderliche Optionen“ haben. Denken Sie darüber nach. Wenn es erforderlich ist, ist es *nicht optional*! Wenn es eine Information gibt, die Ihr Programm unbedingt benötigt, um erfolgreich ausgeführt zu werden, dann sind dafür Positionsargumente da.
Als Beispiel für gutes Design der Kommandozeilenschnittstelle betrachten wir das bescheidene cp-Dienstprogramm zum Kopieren von Dateien. Es macht nicht viel Sinn, zu versuchen, Dateien zu kopieren, ohne ein Ziel und mindestens eine Quelle anzugeben. Daher schlägt cp fehl, wenn Sie es ohne Argumente ausführen. Es hat jedoch eine flexible, nützliche Syntax, die keinerlei Optionen erfordert
cp SOURCE DEST
cp SOURCE ... DEST-DIR
Damit kann man schon ziemlich weit kommen. Die meisten cp-Implementierungen bieten eine Reihe von Optionen, um genau anzupassen, wie die Dateien kopiert werden: Sie können Modus und Änderungszeit beibehalten, Symlinks nicht folgen, vor dem Überschreiben vorhandener Dateien fragen usw. Aber nichts davon lenkt vom Kernauftrag von cp ab, nämlich dem Kopieren einer Datei in eine andere oder mehrerer Dateien in ein anderes Verzeichnis.
Wozu dienen Positionsargumente?¶
Positionsargumente sind für jene Informationen, die Ihr Programm unbedingt, absolut benötigt, um ausgeführt zu werden.
Eine gute Benutzeroberfläche sollte so wenige absolute Anforderungen wie möglich haben. Wenn Ihr Programm 17 verschiedene Informationen benötigt, um erfolgreich ausgeführt zu werden, spielt es kaum eine Rolle, *wie* Sie diese Informationen vom Benutzer erhalten – die meisten Leute werden aufgeben und weggehen, bevor sie das Programm erfolgreich ausführen. Dies gilt unabhängig davon, ob die Benutzeroberfläche eine Kommandozeile, eine Konfigurationsdatei oder eine GUI ist: Wenn Sie so viele Anforderungen an Ihre Benutzer stellen, werden die meisten von ihnen einfach aufgeben.
Kurz gesagt, versuchen Sie, die Menge der Informationen, die Benutzer unbedingt bereitstellen müssen, zu minimieren – verwenden Sie sinnvolle Standardwerte, wo immer möglich. Natürlich möchten Sie auch, dass Ihre Programme einigermaßen flexibel sind. Dafür sind Optionen da. Auch hier spielt es keine Rolle, ob es sich um Einträge in einer Konfigurationsdatei, Widgets im „Einstellungen“-Dialog einer GUI oder um Kommandozeilenoptionen handelt – je mehr Optionen Sie implementieren, desto flexibler ist Ihr Programm und desto komplizierter wird seine Implementierung. Zu viel Flexibilität hat natürlich auch Nachteile; zu viele Optionen können Benutzer überfordern und Ihren Code viel schwerer wartbar machen.
Tutorial¶
Obwohl optparse sehr flexibel und leistungsfähig ist, ist es in den meisten Fällen auch einfach zu verwenden. Dieser Abschnitt behandelt die Codemuster, die für jedes optparse-basierte Programm üblich sind.
Zuerst müssen Sie die Klasse `OptionParser` importieren; dann, früh im Hauptprogramm, erstellen Sie eine `OptionParser`-Instanz
from optparse import OptionParser
...
parser = OptionParser()
Dann können Sie beginnen, Optionen zu definieren. Die grundlegende Syntax ist
parser.add_option(opt_str, ...,
attr=value, ...)
Jede Option hat einen oder mehrere Optionsstrings, wie z. B. -f oder --file, und mehrere Optionsattribute, die optparse mitteilen, was es erwartet und was es tun soll, wenn es diese Option auf der Kommandozeile antrifft.
Typischerweise hat jede Option einen kurzen und einen langen Optionsstring, z. B.
parser.add_option("-f", "--file", ...)
Sie können beliebig viele kurze und lange Optionsstrings definieren (einschließlich null), solange insgesamt mindestens ein Optionsstring vorhanden ist.
Die an OptionParser.add_option() übergebenen Optionsstrings sind effektiv Bezeichnungen für die von diesem Aufruf definierte Option. Der Kürze halber werden wir häufig von dem Antreffen einer Option auf der Kommandozeile sprechen; tatsächlich trifft optparse Optionsstrings an und sucht aus ihnen Optionen heraus.
Sobald alle Ihre Optionen definiert sind, weisen Sie optparse an, die Kommandozeile Ihres Programms zu analysieren
(options, args) = parser.parse_args()
(Wenn Sie möchten, können Sie eine benutzerdefinierte Argumentenliste an parse_args() übergeben, aber das ist selten notwendig: standardmäßig verwendet es sys.argv[1:].)
parse_args() gibt zwei Werte zurück
options, ein Objekt, das Werte für alle Ihre Optionen enthält – z. B. wenn--fileein einzelnes String-Argument nimmt, dann istoptions.fileder vom Benutzer bereitgestellte Dateiname oderNone, wenn der Benutzer diese Option nicht angegeben hatargs, die Liste der Positionsargumente, die nach der Analyse der Optionen übrig bleiben
Dieser Tutorial-Abschnitt behandelt nur die vier wichtigsten Optionsattribute: action, type, dest (Ziel) und help. Von diesen ist action das grundlegendste.
Verständnis von Optionsaktionen¶
Aktionen sagen optparse, was zu tun ist, wenn es eine Option auf der Kommandozeile antrifft. Es gibt eine feste Menge von Aktionen, die fest in optparse kodiert sind; das Hinzufügen neuer Aktionen ist ein fortgeschrittenes Thema, das in Abschnitt Erweiterung von optparse behandelt wird. Die meisten Aktionen weisen optparse an, einen Wert in einer Variablen zu speichern – zum Beispiel, eine Zeichenkette von der Kommandozeile zu nehmen und sie in einem Attribut von options zu speichern.
Wenn Sie keine Optionsaktion angeben, verwendet optparse standardmäßig store.
Die Aktion `store`¶
Die gebräuchlichste Optionsaktion ist store, die optparse anweist, das nächste Argument (oder den Rest des aktuellen Arguments) zu nehmen, sicherzustellen, dass es den richtigen Typ hat, und es an Ihr gewähltes Ziel zu speichern.
Zum Beispiel
parser.add_option("-f", "--file",
action="store", type="string", dest="filename")
Lassen Sie uns nun eine fiktive Kommandozeile erstellen und optparse bitten, sie zu analysieren
args = ["-f", "foo.txt"]
(options, args) = parser.parse_args(args)
Wenn optparse den Optionsstring -f sieht, konsumiert es das nächste Argument, foo.txt, und speichert es in options.filename. Also ist nach diesem Aufruf von parse_args() options.filename "foo.txt".
Einige andere von optparse unterstützte Optionstypen sind int und float. Hier ist eine Option, die ein Integer-Argument erwartet
parser.add_option("-n", type="int", dest="num")
Beachten Sie, dass diese Option keinen langen Optionsstring hat, was vollkommen akzeptabel ist. Außerdem gibt es keine explizite Aktion, da der Standard store ist.
Lassen Sie uns eine weitere fiktive Kommandozeile analysieren. Diesmal werden wir das Optionsargument direkt an die Option quetschen: da -n42 (ein Argument) äquivalent zu -n 42 (zwei Argumente) ist, wird der Code
(options, args) = parser.parse_args(["-n42"])
print(options.num)
gibt 42 aus.
Wenn Sie keinen Typ angeben, nimmt optparse standardmäßig an, dass es sich um einen string handelt. In Kombination mit der Tatsache, dass die Standardaktion store ist, bedeutet dies, dass unser erstes Beispiel viel kürzer sein kann.
parser.add_option("-f", "--file", dest="filename")
Wenn Sie kein Ziel (destination) angeben, ermittelt optparse ein sinnvolles Standardverhalten aus den Optionszeichenfolgen: Wenn die erste lange Optionszeichenfolge --foo-bar lautet, ist das Standardziel foo_bar. Wenn keine langen Optionszeichenfolgen vorhanden sind, betrachtet optparse die erste kurze Optionszeichenfolge: Das Standardziel für -f ist f.
optparse enthält auch den integrierten Typ complex. Das Hinzufügen von Typen wird in Abschnitt Erweiterung von optparse behandelt.
Behandlung von booleschen (Flag-)Optionen¶
Flag-Optionen – bei denen eine Variable auf wahr oder falsch gesetzt wird, wenn eine bestimmte Option gesehen wird – sind ziemlich verbreitet. optparse unterstützt sie mit zwei separaten Aktionen: store_true und store_false. Sie könnten zum Beispiel ein verbose-Flag haben, das mit -v eingeschaltet und mit -q ausgeschaltet wird.
parser.add_option("-v", action="store_true", dest="verbose")
parser.add_option("-q", action="store_false", dest="verbose")
Hier haben wir zwei verschiedene Optionen mit demselben Ziel, was völlig in Ordnung ist. (Das bedeutet nur, dass Sie bei der Festlegung von Standardwerten etwas vorsichtig sein müssen – siehe unten.)
Wenn optparse auf der Kommandozeile auf -v stößt, setzt es options.verbose auf True; wenn es auf -q stößt, wird options.verbose auf False gesetzt.
Andere Aktionen¶
Einige weitere von optparse unterstützte Aktionen sind:
"store_const"Speichern eines konstanten Werts, der über
Option.constvoreingestellt wurde."append"Anhängen des Arguments dieser Option an eine Liste.
"count"Inkrementieren eines Zählers um eins.
"callback"Aufrufen einer angegebenen Funktion.
Diese werden in Abschnitt Referenzhandbuch und Abschnitt Option Callbacks behandelt.
Standardwerte¶
Alle obigen Beispiele beinhalten das Setzen einer Variable (des „Ziels“), wenn bestimmte Kommandozeilenoptionen gesehen werden. Was passiert, wenn diese Optionen nie gesehen werden? Da wir keine Standardwerte angegeben haben, werden sie alle auf None gesetzt. Das ist normalerweise in Ordnung, aber manchmal möchte man mehr Kontrolle. optparse ermöglicht es Ihnen, für jedes Ziel einen Standardwert anzugeben, der zugewiesen wird, bevor die Kommandozeile geparst wird.
Betrachten Sie zunächst das verbose/quiet-Beispiel. Wenn wir möchten, dass optparse verbose auf True setzt, es sei denn, -q wird gesehen, dann können wir das so machen:
parser.add_option("-v", action="store_true", dest="verbose", default=True)
parser.add_option("-q", action="store_false", dest="verbose")
Da Standardwerte für das *Ziel* und nicht für eine bestimmte Option gelten und diese beiden Optionen zufällig dasselbe Ziel haben, ist dies exakt äquivalent.
parser.add_option("-v", action="store_true", dest="verbose")
parser.add_option("-q", action="store_false", dest="verbose", default=True)
Betrachten Sie dies:
parser.add_option("-v", action="store_true", dest="verbose", default=False)
parser.add_option("-q", action="store_false", dest="verbose", default=True)
Auch hier ist der Standardwert für verbose True: Der zuletzt für ein bestimmtes Ziel angegebene Standardwert zählt.
Eine klarere Methode zur Angabe von Standardwerten ist die Methode set_defaults() von OptionParser, die Sie jederzeit vor dem Aufruf von parse_args() aufrufen können.
parser.set_defaults(verbose=True)
parser.add_option(...)
(options, args) = parser.parse_args()
Wie zuvor gilt: Der zuletzt für ein bestimmtes Optionsziel angegebene Wert zählt. Verwenden Sie zur Klarheit lieber eine der beiden Methoden zur Festlegung von Standardwerten, nicht beide.
Hilfetexterstellung¶
optparse's Fähigkeit, automatisch Hilfe- und Nutzungstexte zu generieren, ist nützlich für die Erstellung benutzerfreundlicher Kommandozeilen-Schnittstellen. Alles, was Sie tun müssen, ist, für jede Option einen help-Wert anzugeben und optional eine kurze Nutzungsmeldung für Ihr gesamtes Programm. Hier ist ein OptionParser, der mit benutzerfreundlichen (dokumentierten) Optionen gefüllt ist:
usage = "usage: %prog [options] arg1 arg2"
parser = OptionParser(usage=usage)
parser.add_option("-v", "--verbose",
action="store_true", dest="verbose", default=True,
help="make lots of noise [default]")
parser.add_option("-q", "--quiet",
action="store_false", dest="verbose",
help="be vewwy quiet (I'm hunting wabbits)")
parser.add_option("-f", "--filename",
metavar="FILE", help="write output to FILE")
parser.add_option("-m", "--mode",
default="intermediate",
help="interaction mode: novice, intermediate, "
"or expert [default: %default]")
Wenn optparse auf der Kommandozeile entweder -h oder --help erkennt oder wenn Sie einfach parser.print_help() aufrufen, gibt es Folgendes auf die Standardausgabe aus:
Usage: <yourscript> [options] arg1 arg2
Options:
-h, --help show this help message and exit
-v, --verbose make lots of noise [default]
-q, --quiet be vewwy quiet (I'm hunting wabbits)
-f FILE, --filename=FILE
write output to FILE
-m MODE, --mode=MODE interaction mode: novice, intermediate, or
expert [default: intermediate]
(Wenn die Hilfeberechtigung durch eine Hilfeoption ausgelöst wird, beendet optparse die Ausgabe nach dem Drucken des Hilfetextes.)
Hier geschieht viel, um optparse zu helfen, die bestmögliche Hilfemeldung zu generieren.
Das Skript definiert seine eigene Nutzungsmeldung.
usage = "usage: %prog [options] arg1 arg2"
optparseerweitert%progin der Nutzungszeichenfolge zum Namen des aktuellen Programms, d. h. zuos.path.basename(sys.argv[0]). Die erweiterte Zeichenfolge wird dann vor der detaillierten Optionshilfe ausgegeben.Wenn Sie keine Nutzungszeichenfolge angeben, verwendet
optparseeinen einfachen, aber sinnvollen Standardwert:"Usage: %prog [options]", was in Ordnung ist, wenn Ihr Skript keine positionsabhängigen Argumente annimmt.Jede Option definiert eine Hilfezeichenfolge und kümmert sich nicht um Zeilenumbrüche –
optparsekümmert sich um den Zeilenumbruch und sorgt dafür, dass die Hilfsausgabe gut aussieht.Optionen, die einen Wert annehmen, zeigen dies in ihrer automatisch generierten Hilfemeldung an, z. B. für die Option „mode“:
-m MODE, --mode=MODE
Hier wird „MODE“ die Metavariable genannt: Sie steht für das Argument, das der Benutzer voraussichtlich an
-m/--modeübergeben soll. Standardmäßig konvertiertoptparseden Namen der Zielvariablen in Großbuchstaben und verwendet diesen für die Metavariable. Manchmal ist das nicht gewünscht – zum Beispiel setzt die Option--filenameexplizitmetavar="FILE", was zu dieser automatisch generierten Optionsbeschreibung führt:-f FILE, --filename=FILE
Dies ist jedoch wichtiger als nur Platzersparnis: Der manuell geschriebene Hilfetext verwendet die Metavariable
FILE, um den Benutzer darauf hinzuweisen, dass eine Verbindung zwischen der halbformalen Syntax-f FILEund der informellen semantischen Beschreibung „Ausgabe nach FILE schreiben“ besteht. Dies ist eine einfache, aber effektive Möglichkeit, Ihren Hilfetext für Endbenutzer deutlich klarer und nützlicher zu gestalten.Optionen, die einen Standardwert haben, können
%defaultin der Hilfezeichenfolge enthalten –optparseersetzt es durchstr()des Standardwerts der Option. Wenn eine Option keinen Standardwert hat (oder der StandardwertNoneist), expandiert%defaultzunone.
Optionen gruppieren¶
Wenn Sie mit vielen Optionen arbeiten, ist es praktisch, diese Optionen für eine bessere Hilfsausgabe zu gruppieren. Ein OptionParser kann mehrere Optionsgruppen enthalten, von denen jede mehrere Optionen enthalten kann.
Eine Optionsgruppe wird mit der Klasse OptionGroup erhalten.
- class optparse.OptionGroup(parser, title, description=None)¶
wobei
parser die
OptionParser-Instanz ist, in die die Gruppe eingefügt wird.title der Titel der Gruppe ist.
description, optional, eine lange Beschreibung der Gruppe ist.
OptionGroup erbt von OptionContainer (wie OptionParser), und so kann die Methode add_option() verwendet werden, um eine Option zur Gruppe hinzuzufügen.
Sobald alle Optionen deklariert sind, wird die Gruppe durch die Methode add_option_group() des OptionParser zum zuvor definierten Parser hinzugefügt.
Fortfahrend mit dem im vorherigen Abschnitt definierten Parser ist das Hinzufügen einer OptionGroup zu einem Parser einfach:
group = OptionGroup(parser, "Dangerous Options",
"Caution: use these options at your own risk. "
"It is believed that some of them bite.")
group.add_option("-g", action="store_true", help="Group option.")
parser.add_option_group(group)
Dies würde zu folgender Hilfsausgabe führen:
Usage: <yourscript> [options] arg1 arg2
Options:
-h, --help show this help message and exit
-v, --verbose make lots of noise [default]
-q, --quiet be vewwy quiet (I'm hunting wabbits)
-f FILE, --filename=FILE
write output to FILE
-m MODE, --mode=MODE interaction mode: novice, intermediate, or
expert [default: intermediate]
Dangerous Options:
Caution: use these options at your own risk. It is believed that some
of them bite.
-g Group option.
Ein etwas vollständigeres Beispiel könnte die Verwendung von mehr als einer Gruppe beinhalten: immer noch eine Erweiterung des vorherigen Beispiels.
group = OptionGroup(parser, "Dangerous Options",
"Caution: use these options at your own risk. "
"It is believed that some of them bite.")
group.add_option("-g", action="store_true", help="Group option.")
parser.add_option_group(group)
group = OptionGroup(parser, "Debug Options")
group.add_option("-d", "--debug", action="store_true",
help="Print debug information")
group.add_option("-s", "--sql", action="store_true",
help="Print all SQL statements executed")
group.add_option("-e", action="store_true", help="Print every action done")
parser.add_option_group(group)
Dies führt zu folgender Ausgabe:
Usage: <yourscript> [options] arg1 arg2
Options:
-h, --help show this help message and exit
-v, --verbose make lots of noise [default]
-q, --quiet be vewwy quiet (I'm hunting wabbits)
-f FILE, --filename=FILE
write output to FILE
-m MODE, --mode=MODE interaction mode: novice, intermediate, or expert
[default: intermediate]
Dangerous Options:
Caution: use these options at your own risk. It is believed that some
of them bite.
-g Group option.
Debug Options:
-d, --debug Print debug information
-s, --sql Print all SQL statements executed
-e Print every action done
Eine weitere interessante Methode, insbesondere bei der programmatischen Arbeit mit Optionsgruppen, ist:
- OptionParser.get_option_group(opt_str)¶
Gibt die
OptionGroupzurück, zu der die kurze oder lange Optionszeichenfolge opt_str gehört (z. B.'-o'oder'--option'). Wenn keine solcheOptionGroupvorhanden ist, wirdNonezurückgegeben.
Drucken einer Versionszeichenfolge¶
Ähnlich wie die kurze Nutzungsmeldung kann optparse auch eine Versionszeichenfolge für Ihr Programm ausgeben. Sie müssen die Zeichenfolge als version-Argument an OptionParser übergeben.
parser = OptionParser(usage="%prog [-f] [-q]", version="%prog 1.0")
%prog wird genauso erweitert wie in usage. Abgesehen davon kann version alles enthalten, was Sie möchten. Wenn Sie es angeben, fügt optparse automatisch eine --version-Option zu Ihrem Parser hinzu. Wenn es diese Option auf der Kommandozeile erkennt, erweitert es Ihre version-Zeichenfolge (durch Ersetzen von %prog), gibt sie auf stdout aus und beendet sich.
Wenn Ihr Skript zum Beispiel /usr/bin/foo heißt:
$ /usr/bin/foo --version
foo 1.0
Die folgenden beiden Methoden können verwendet werden, um die version-Zeichenfolge auszugeben und abzurufen:
- OptionParser.print_version(file=None)¶
Gibt die Versionsmeldung für das aktuelle Programm (
self.version) an file (standardmäßig stdout) aus. Wie beiprint_usage()wird jede Vorkommens von%proginself.versiondurch den Namen des aktuellen Programms ersetzt. Es tut nichts, wennself.versionleer oder undefiniert ist.
- OptionParser.get_version()¶
Wie
print_version(), gibt aber die Versionszeichenfolge zurück, anstatt sie auszugeben.
Wie optparse Fehler behandelt¶
Es gibt zwei Hauptklassen von Fehlern, um die sich optparse kümmern muss: Programmierfehler und Benutzerfehler. Programmierfehler sind in der Regel fehlerhafte Aufrufe von OptionParser.add_option(), z. B. ungültige Optionszeichenfolgen, unbekannte Optionsattribute, fehlende Optionsattribute usw. Diese werden auf die übliche Weise behandelt: Auslösen einer Ausnahme (entweder optparse.OptionError oder TypeError) und das Programm abstürzen lassen.
Die Behandlung von Benutzerfehlern ist viel wichtiger, da diese garantiert auftreten, unabhängig davon, wie stabil Ihr Code ist. optparse kann einige Benutzerfehler automatisch erkennen, wie z. B. ungültige Optionsargumente (Übergabe von -n 4x, wobei -n ein ganzzahliges Argument erwartet), fehlende Argumente (-n am Ende der Kommandozeile, wobei -n ein Argument eines beliebigen Typs erwartet). Außerdem können Sie OptionParser.error() aufrufen, um eine anwendungsdefinierte Fehlerbedingung zu signalisieren.
(options, args) = parser.parse_args()
...
if options.a and options.b:
parser.error("options -a and -b are mutually exclusive")
In beiden Fällen behandelt optparse den Fehler auf die gleiche Weise: Es gibt die Nutzungsmeldung des Programms und eine Fehlermeldung auf stderr aus und beendet sich mit dem Fehlerstatus 2.
Betrachten Sie das erste Beispiel oben, bei dem der Benutzer 4x an eine Option übergibt, die eine Ganzzahl erwartet:
$ /usr/bin/foo -n 4x
Usage: foo [options]
foo: error: option -n: invalid integer value: '4x'
Oder wenn der Benutzer überhaupt keinen Wert übergibt:
$ /usr/bin/foo -n
Usage: foo [options]
foo: error: -n option requires an argument
optparse-generierte Fehlermeldungen erwähnen immer die Option, die mit dem Fehler zusammenhängt. Stellen Sie sicher, dass Sie dasselbe tun, wenn Sie OptionParser.error() aus Ihrem Anwendungscode aufrufen.
Wenn das Standardverhalten von optparse zur Fehlerbehandlung nicht Ihren Bedürfnissen entspricht, müssen Sie OptionParser unterklassifizieren und seine Methoden exit() und/oder error() überschreiben.
Alles zusammenfügen¶
So sehen optparse-basierte Skripte normalerweise aus:
from optparse import OptionParser
...
def main():
usage = "usage: %prog [options] arg"
parser = OptionParser(usage)
parser.add_option("-f", "--file", dest="filename",
help="read data from FILENAME")
parser.add_option("-v", "--verbose",
action="store_true", dest="verbose")
parser.add_option("-q", "--quiet",
action="store_false", dest="verbose")
...
(options, args) = parser.parse_args()
if len(args) != 1:
parser.error("incorrect number of arguments")
if options.verbose:
print("reading %s..." % options.filename)
...
if __name__ == "__main__":
main()
Referenzhandbuch¶
Erstellen des Parsers¶
Der erste Schritt bei der Verwendung von optparse ist die Erstellung einer OptionParser-Instanz.
- class optparse.OptionParser(...)¶
Der Konstruktor von OptionParser hat keine erforderlichen Argumente, aber eine Reihe von optionalen Schlüsselwortargumenten. Sie sollten diese immer als Schlüsselwortargumente übergeben, d. h. verlassen Sie sich nicht auf die Reihenfolge, in der die Argumente deklariert sind.
usage(Standard:"%prog [options]")Die Nutzung zusammenfassung, die ausgegeben wird, wenn Ihr Programm falsch ausgeführt wird oder mit einer Hilfeoption. Wenn
optparsedie Nutzungszeichenfolge ausgibt, erweitert es%progzuos.path.basename(sys.argv[0])(oder zuprog, wenn Sie dieses Schlüsselwortargument übergeben haben). Um eine Nutzungsnachricht zu unterdrücken, übergeben Sie den speziellen Wertoptparse.SUPPRESS_USAGE.option_list(Standard:[])Eine Liste von Option-Objekten, um den Parser zu füllen. Die Optionen in
option_listwerden nach allen Optionen instandard_option_list(ein Klassenattribut, das von OptionParser-Unterklassen festgelegt werden kann), aber vor allen Versions- oder Hilfeoptionen hinzugefügt. Veraltet; verwenden Sie stattdessen nach dem Erstellen des Parsersadd_option().option_class(Standard: optparse.Option)Klasse, die beim Hinzufügen von Optionen zum Parser in
add_option()verwendet werden soll.version(Standard:None)Eine Versionszeichenfolge, die ausgegeben wird, wenn der Benutzer eine Versionsoption angibt. Wenn Sie einen wahren Wert für
versionangeben, fügtoptparseautomatisch eine Versionsoption mit der einzelnen Optionszeichenfolge--versionhinzu. Der Unterstring%progwird genauso erweitert wie fürusage.conflict_handler(Standard:"error")Gibt an, was zu tun ist, wenn Optionen mit widersprüchlichen Optionszeichenfolgen zum Parser hinzugefügt werden; siehe Abschnitt Konflikte zwischen Optionen.
description(Standard:None)Ein Textabsatz mit einer kurzen Übersicht über Ihr Programm.
optparseformatiert diesen Absatz neu, um ihn an die aktuelle Terminalbreite anzupassen, und gibt ihn aus, wenn der Benutzer Hilfe anfordert (nachusage, aber vor der Liste der Optionen).formatter(Standard: ein neuesIndentedHelpFormatter)Eine Instanz von optparse.HelpFormatter, die zum Drucken von Hilfetexten verwendet wird.
optparsebietet zwei konkrete Klassen für diesen Zweck: IndentedHelpFormatter und TitledHelpFormatter.add_help_option(Standard:True)Wenn wahr, fügt
optparseeine Hilfeoption (mit den Optionszeichenfolgen-hund--help) zum Parser hinzu.progDie Zeichenfolge, die zum Erweitern von
%proginusageundversionanstelle vonos.path.basename(sys.argv[0])verwendet wird.epilog(Standard:None)Ein Textabsatz mit Hilfetext, der nach der Optionshilfe ausgegeben wird.
Befüllen des Parsers¶
Es gibt mehrere Möglichkeiten, den Parser mit Optionen zu füllen. Der bevorzugte Weg ist die Verwendung von OptionParser.add_option(), wie in Abschnitt Tutorial gezeigt. add_option() kann auf eine von zwei Arten aufgerufen werden:
einer Option-Instanz übergeben (wie von
make_option()zurückgegeben)beliebige Kombination von Positions- und Schlüsselwortargumenten übergeben, die für
make_option()akzeptabel sind (d. h. für den Option-Konstruktor), und es wird die Option-Instanz für Sie erstellt
Die andere Alternative ist, dem OptionParser-Konstruktor eine Liste von vorab erstellten Option-Instanzen zu übergeben, wie in
option_list = [
make_option("-f", "--filename",
action="store", type="string", dest="filename"),
make_option("-q", "--quiet",
action="store_false", dest="verbose"),
]
parser = OptionParser(option_list=option_list)
(make_option() ist eine Factory-Funktion zum Erstellen von Option-Instanzen; derzeit ist sie ein Alias für den Option-Konstruktor. Eine zukünftige Version von optparse kann Option in mehrere Klassen aufteilen, und make_option() wählt die richtige Klasse zum Instanziieren aus. Instanziieren Sie Option nicht direkt.)
Optionen definieren¶
Jede Option-Instanz repräsentiert eine Menge synonyme Kommandozeilen-Option-Strings, z. B. -f und --file. Sie können beliebig viele kurze oder lange Options-Strings angeben, aber Sie müssen mindestens einen Options-String insgesamt angeben.
Der kanonische Weg, eine Option-Instanz zu erstellen, ist über die add_option()-Methode von OptionParser.
- OptionParser.add_option(option)¶
- OptionParser.add_option(*opt_str, attr=value, ...)
Um eine Option nur mit einem kurzen Options-String zu definieren
parser.add_option("-f", attr=value, ...)
Und um eine Option nur mit einem langen Options-String zu definieren
parser.add_option("--foo", attr=value, ...)
Die Schlüsselwortargumente definieren Attribute des neuen Option-Objekts. Das wichtigste Options-Attribut ist
action, und es bestimmt weitgehend, welche anderen Attribute relevant oder erforderlich sind. Wenn Sie irrelevante Options-Attribute übergeben oder erforderliche nicht übergeben, löstoptparseeineOptionError-Ausnahme aus, die Ihren Fehler erklärt.Die Aktion einer Option bestimmt, was
optparsetut, wenn es diese Option auf der Kommandozeile findet. Die Standard-Option-Aktionen, die fest inoptparseeingebaut sind, sind"store"speichert das Argument dieser Option (Standard)
"store_const"Speichern eines konstanten Werts, der über
Option.constvoreingestellt wurde."store_true"speichert
True"store_false"speichert
False"append"Anhängen des Arguments dieser Option an eine Liste.
"append_const"fügt einen konstanten Wert zu einer Liste hinzu, die über
Option.constvoreingestellt wurde"count"Inkrementieren eines Zählers um eins.
"callback"Aufrufen einer angegebenen Funktion.
"help"druckt eine Nutzungsnachricht, die alle Optionen und deren Dokumentation enthält
(Wenn Sie keine Aktion angeben, ist die Standardaktion
"store". Für diese Aktion können Sie auch die Options-Attributetypeunddestangeben; siehe Standard-Option-Aktionen.)
Wie Sie sehen, beinhalten die meisten Aktionen das Speichern oder Aktualisieren eines Wertes an einer bestimmten Stelle. optparse erstellt dafür immer ein spezielles Objekt, konventionell options genannt, das eine Instanz von optparse.Values ist.
- class optparse.Values¶
Ein Objekt, das geparste Argumentnamen und Werte als Attribute enthält. Wird normalerweise durch den Aufruf beim Aufruf von
OptionParser.parse_args()erstellt und kann durch eine benutzerdefinierte Unterklasse überschrieben werden, die an das values-Argument vonOptionParser.parse_args()übergeben wird (wie in Argumente parsen beschrieben).
Options-Argumente (und verschiedene andere Werte) werden als Attribute dieses Objekts gespeichert, entsprechend dem Options-Attribut dest (Ziel).
Zum Beispiel, wenn Sie aufrufen
parser.parse_args()
eines der ersten Dinge, die optparse tut, ist die Erstellung des options-Objekts
options = Values()
Wenn eine der Optionen in diesem Parser definiert ist mit
parser.add_option("-f", "--file", action="store", type="string", dest="filename")
und die zu parsendende Kommandozeile eine der folgenden enthält
-ffoo
-f foo
--file=foo
--file foo
dann wird optparse, wenn es diese Option sieht, das Äquivalent von
options.filename = "foo"
Die Options-Attribute type und dest sind fast so wichtig wie action, aber action ist die einzige, die für alle Optionen sinnvoll ist.
Options-Attribute¶
- class optparse.Option¶
Ein einzelnes Kommandozeilen-Argument mit verschiedenen Attributen, die als Schlüsselwortargumente an den Konstruktor übergeben werden. Normalerweise erstellt mit
OptionParser.add_option()statt direkt, und kann durch eine benutzerdefinierte Klasse über das option_class-Argument fürOptionParserüberschrieben werden.
Die folgenden Options-Attribute können als Schlüsselwortargumente an OptionParser.add_option() übergeben werden. Wenn Sie ein Options-Attribut übergeben, das für eine bestimmte Option nicht relevant ist, oder ein erforderliches Options-Attribut nicht übergeben, löst optparse OptionError aus.
- Option.action¶
(Standard:
"store")Bestimmt das Verhalten von
optparse, wenn diese Option auf der Kommandozeile gesehen wird; die verfügbaren Optionen sind hier dokumentiert.
- Option.type¶
(Standard:
"string")Der Argumenttyp, der von dieser Option erwartet wird (z. B.
"string"oder"int"); die verfügbaren Option-Typen sind hier dokumentiert.
- Option.dest¶
(Standard: abgeleitet von Options-Strings)
Wenn die Aktion der Option das Schreiben oder Modifizieren eines Wertes an einer bestimmten Stelle impliziert, teilt dies
optparsemit, wohin es schreiben soll:destnennt ein Attribut desoptions-Objekts, dasoptparsebeim Parsen der Kommandozeile aufbaut.
- Option.default¶
Der Wert, der für das Ziel dieser Option verwendet werden soll, wenn die Option nicht auf der Kommandozeile gefunden wird. Siehe auch
OptionParser.set_defaults().
- Option.nargs¶
(Standard: 1)
Wie viele Argumente vom Typ
typekonsumiert werden sollen, wenn diese Option gesehen wird. Wenn > 1, speichertoptparseein Tupel von Werten indest.
- Option.const¶
Für Aktionen, die einen konstanten Wert speichern, der konstante Wert, der gespeichert werden soll.
- Option.choices¶
Für Optionen vom Typ
"choice", die Liste der Zeichenketten, aus denen der Benutzer wählen kann.
- Option.callback¶
Für Optionen mit der Aktion
"callback", das aufzurufende callable, wenn diese Option gesehen wird. Siehe Abschnitt Option Callbacks für Details zu den Argumenten, die an das callable übergeben werden.
- Option.callback_args¶
- Option.callback_kwargs¶
Zusätzliche positionsbezogene und Schlüsselwortargumente, die an
callbackübergeben werden, nachdem die vier Standard-Callback-Argumente.
- Option.help¶
Hilfetext, der für diese Option beim Auflisten aller verfügbaren Optionen gedruckt wird, nachdem der Benutzer eine
help-Option (wie z. B.--help) bereitgestellt hat. Wenn kein Hilfetext angegeben wird, wird die Option ohne Hilfetext aufgelistet. Um diese Option zu verbergen, verwenden Sie den Sonderwertoptparse.SUPPRESS_HELP.
Standard-Option-Aktionen¶
Die verschiedenen Options-Aktionen haben leicht unterschiedliche Anforderungen und Effekte. Die meisten Aktionen haben mehrere relevante Options-Attribute, die Sie angeben können, um das Verhalten von optparse zu steuern; einige wenige haben erforderliche Attribute, die Sie für jede Option angeben müssen, die diese Aktion verwendet.
"store"[relevant:type,dest,nargs,choices]Die Option muss von einem Argument gefolgt werden, das gemäß
typein einen Wert konvertiert und indestgespeichert wird. Wennnargs> 1, werden mehrere Argumente von der Kommandozeile konsumiert; alle werden gemäßtypekonvertiert und als Tupel indestgespeichert. Siehe den Abschnitt Standard-Option-Typen.Wenn
choicesangegeben ist (eine Liste oder ein Tupel von Zeichenketten), ist der Standardtyp"choice".Wenn
typenicht angegeben ist, ist der Standard"string".Wenn
destnicht angegeben ist, leitetoptparseein Ziel vom ersten langen Options-String ab (z. B.--foo-barimpliziertfoo_bar). Wenn keine langen Options-Strings vorhanden sind, leitetoptparseein Ziel vom ersten kurzen Options-String ab (z. B.-fimpliziertf).Beispiel
parser.add_option("-f") parser.add_option("-p", type="float", nargs=3, dest="point")
Beim Parsen der Kommandozeile
-f foo.txt -p 1 -3.5 4 -fbar.txt
optparsesetztoptions.f = "foo.txt" options.point = (1.0, -3.5, 4.0) options.f = "bar.txt"
"store_const"[erforderlich:const; relevant:dest]Der Wert
constwird indestgespeichert.Beispiel
parser.add_option("-q", "--quiet", action="store_const", const=0, dest="verbose") parser.add_option("-v", "--verbose", action="store_const", const=1, dest="verbose") parser.add_option("--noisy", action="store_const", const=2, dest="verbose")
Wenn
--noisygesehen wird, setztoptparseoptions.verbose = 2
"store_true"[relevant:dest]Ein Sonderfall von
"store_const", derTruenachdestspeichert."store_false"[relevant:dest]Wie
"store_true", aber speichertFalse.Beispiel
parser.add_option("--clobber", action="store_true", dest="clobber") parser.add_option("--no-clobber", action="store_false", dest="clobber")
"append"[relevant:type,dest,nargs,choices]Die Option muss von einem Argument gefolgt werden, das an die Liste in
destangehängt wird. Wenn kein Standardwert fürdestangegeben ist, wird eine leere Liste automatisch erstellt, wennoptparsediese Option zum ersten Mal auf der Kommandozeile findet. Wennnargs> 1, werden mehrere Argumente konsumiert und ein Tupel der Längenargsandestangehängt.Die Standardwerte für
typeunddestsind dieselben wie für die Aktion"store".Beispiel
parser.add_option("-t", "--tracks", action="append", type="int")
Wenn
-t3auf der Kommandozeile gesehen wird, führtoptparsedas Äquivalent vonoptions.tracks = [] options.tracks.append(int("3"))
Wenn, ein wenig später,
--tracks=4gesehen wird, tut esoptions.tracks.append(int("4"))
Die Aktion
appendruft die Methodeappendauf dem aktuellen Wert der Option auf. Das bedeutet, dass jeder angegebene Standardwert eineappend-Methode haben muss. Das bedeutet auch, dass, wenn der Standardwert nicht leer ist, die Standardelemente im geparsten Wert für die Option vorhanden sind, wobei alle Werte von der Kommandozeile nach diesen Standardwerten angehängt werden.>>> parser.add_option("--files", action="append", default=['~/.mypkg/defaults']) >>> opts, args = parser.parse_args(['--files', 'overrides.mypkg']) >>> opts.files ['~/.mypkg/defaults', 'overrides.mypkg']
"append_const"[erforderlich:const; relevant:dest]Wie
"store_const", aber der Wertconstwird andestangehängt; wie bei"append", hatdeststandardmäßigNone, und eine leere Liste wird automatisch erstellt, wenn die Option zum ersten Mal angetroffen wird."count"[relevant:dest]Inkrementiert die Ganzzahl, die unter
destgespeichert ist. Wenn kein Standardwert angegeben ist, wirddestauf Null gesetzt, bevor es beim ersten Mal inkrementiert wird.Beispiel
parser.add_option("-v", action="count", dest="verbosity")
Wenn
-vzum ersten Mal auf der Kommandozeile gesehen wird, machtoptparsedas Äquivalent vonoptions.verbosity = 0 options.verbosity += 1
Jede nachfolgendeoccurrence von
-vführt zuoptions.verbosity += 1
"callback"[erforderlich:callback; relevant:type,nargs,callback_args,callback_kwargs]Ruft die Funktion auf, die von
callbackangegeben wird, die aufgerufen wird alsfunc(option, opt_str, value, parser, *args, **kwargs)
Siehe Abschnitt Option Callbacks für weitere Details.
"help"Druckt eine vollständige Hilfemeldung für alle Optionen im aktuellen Options-Parser. Die Hilfemeldung wird aus der
usage-Zeichenkette, die an den Konstruktor von OptionParser übergeben wird, und derhelp-Zeichenkette, die an jede Option übergeben wird, zusammengestellt.Wenn für eine Option keine
help-Zeichenkette angegeben ist, wird sie trotzdem in der Hilfemeldung aufgeführt. Um eine Option vollständig auszulassen, verwenden Sie den Sonderwertoptparse.SUPPRESS_HELP.optparsefügt automatisch einehelp-Option zu allen OptionParsers hinzu, sodass Sie normalerweise keine erstellen müssen.Beispiel
from optparse import OptionParser, SUPPRESS_HELP # usually, a help option is added automatically, but that can # be suppressed using the add_help_option argument parser = OptionParser(add_help_option=False) parser.add_option("-h", "--help", action="help") parser.add_option("-v", action="store_true", dest="verbose", help="Be moderately verbose") parser.add_option("--file", dest="filename", help="Input file to read data from") parser.add_option("--secret", help=SUPPRESS_HELP)
Wenn
optparseentweder-hoder--helpin der Kommandozeile sieht, gibt es eine ähnliche Hilfemeldung wie die folgende an stdout aus (vorausgesetztsys.argv[0]ist"foo.py")Usage: foo.py [options] Options: -h, --help Show this help message and exit -v Be moderately verbose --file=FILENAME Input file to read data from
Nachdem die Hilfemeldung ausgegeben wurde, beendet
optparseIhren Prozess mitsys.exit(0)."version"Gibt die dem OptionParser übergebene Versionsnummer an stdout aus und wird beendet. Die Versionsnummer wird tatsächlich von der Methode
print_version()des OptionParser formatiert und ausgegeben. Im Allgemeinen nur relevant, wenn das Argumentversiondem Konstruktor des OptionParser übergeben wurde. Wie beihelp-Optionen werden Sie seltenversion-Optionen erstellen, daoptparsediese automatisch hinzufügt, wenn sie benötigt werden.
Standard-Optionstypen¶
optparse hat fünf eingebaute Optionstypen: "string", "int", "choice", "float" und "complex". Wenn Sie neue Optionstypen hinzufügen müssen, siehe Abschnitt Erweiterung von optparse.
Argumente für Zeichenkettenoptionen werden nicht überprüft oder konvertiert. Der Text in der Kommandozeile wird unverändert im Ziel (oder an den Callback übergeben) gespeichert.
Ganzzahlige Argumente (Typ "int") werden wie folgt geparst:
Wenn die Zahl mit
0xbeginnt, wird sie als Hexadezimalzahl geparst.Wenn die Zahl mit
0beginnt, wird sie als Oktalzahl geparst.Wenn die Zahl mit
0bbeginnt, wird sie als Binärzahl geparst.Andernfalls wird die Zahl als Dezimalzahl geparst.
Die Konvertierung erfolgt durch Aufruf von int() mit der entsprechenden Basis (2, 8, 10 oder 16). Wenn dies fehlschlägt, wird auch optparse fehlschlagen, wenn auch mit einer nützlicheren Fehlermeldung.
Argumente für "float"- und "complex"-Optionen werden direkt mit float() und complex() konvertiert, mit ähnlicher Fehlerbehandlung.
"choice"-Optionen sind eine Unterart von "string"-Optionen. Das Attribut choices der Option (eine Sequenz von Zeichenketten) definiert die Menge der zulässigen Optionsargumente. optparse.check_choice() vergleicht die vom Benutzer bereitgestellten Optionsargumente mit dieser Masterliste und löst eine OptionValueError aus, wenn eine ungültige Zeichenkette angegeben wird.
Argumente parsen¶
Der Sinn der Erstellung und Befüllung eines OptionParsers besteht darin, seine Methode parse_args() aufzurufen.
- OptionParser.parse_args(args=None, values=None)¶
Parst die Kommandozeilenoptionen, die in args gefunden werden.
Die Eingabeparameter sind:
argsdie zu verarbeitende Liste von Argumenten (Standard:
sys.argv[1:])Werteein
Values-Objekt zum Speichern von Optionsargumenten (Standard: eine neue Instanz vonValues) – wenn Sie ein vorhandenes Objekt übergeben, werden die Standardwerte der Optionen nicht darauf initialisiert
und der Rückgabewert ist ein Paar
(options, args), wobeioptionsdasselbe Objekt, das als values übergeben wurde, oder die von
optparseerstellteoptparse.Values-Instanzargsdie verbleibenden positionellen Argumente, nachdem alle Optionen verarbeitet wurden
Die häufigste Verwendung ist, weder ein Schlüsselwortargument anzugeben. Wenn Sie values angeben, wird dieses durch wiederholte Aufrufe von setattr() (ungefähr einer für jedes Optionsargument, das in ein Optionsziel gespeichert wird) modifiziert und von parse_args() zurückgegeben.
Wenn parse_args() auf Fehler in der Argumentliste stößt, ruft es die Methode error() des OptionParser mit einer entsprechenden Fehlermeldung für Endbenutzer auf. Dies beendet Ihren Prozess schließlich mit dem Exit-Status 2 (dem traditionellen Unix-Exit-Status für Kommandozeilenfehler).
Optionen-Parser abfragen und manipulieren¶
Das Standardverhalten des Optionen-Parsers kann leicht angepasst werden, und Sie können auch Ihren Optionen-Parser untersuchen, um zu sehen, was vorhanden ist. OptionParser bietet mehrere Methoden, die Ihnen dabei helfen:
- OptionParser.disable_interspersed_args()¶
Setzt das Parsing so, dass es beim ersten Nicht-Option stoppt. Wenn zum Beispiel
-aund-beinfache Optionen sind, die keine Argumente nehmen, akzeptiertoptparsenormalerweise diese Syntax:prog -a arg1 -b arg2
und behandelt sie als äquivalent zu:
prog -a -b arg1 arg2
Um diese Funktion zu deaktivieren, rufen Sie
disable_interspersed_args()auf. Dies stellt die traditionelle Unix-Syntax wieder her, bei der das Parsing von Optionen mit dem ersten Nicht-Optionsargument stoppt.Verwenden Sie dies, wenn Sie einen Kommando-Prozessor haben, der ein anderes Kommando ausführt, das eigene Optionen hat und Sie sicherstellen möchten, dass diese Optionen nicht verwechselt werden. Zum Beispiel könnte jedes Kommando einen anderen Satz von Optionen haben.
- OptionParser.enable_interspersed_args()¶
Setzt das Parsing so, dass es nicht beim ersten Nicht-Option stoppt, wodurch Schalter mit Kommandoargumenten durchmischt werden können. Dies ist das Standardverhalten.
- OptionParser.get_option(opt_str)¶
Gibt die Option-Instanz mit der Optionszeichenkette opt_str zurück oder
None, wenn keine Optionen diese Optionszeichenkette haben.
- OptionParser.has_option(opt_str)¶
Gibt
Truezurück, wenn der OptionParser eine Option mit der Optionszeichenkette opt_str hat (z. B.-qoder--verbose).
- OptionParser.remove_option(opt_str)¶
Wenn der
OptionParsereine Option hat, die opt_str entspricht, wird diese Option entfernt. Wenn diese Option andere Optionszeichenketten bereitgestellt hat, werden alle diese Optionszeichenketten ungültig. Wenn opt_str in keiner Option vorkommt, die zu diesemOptionParsergehört, wirdValueErrorausgelöst.
Konflikte zwischen Optionen¶
Wenn Sie nicht vorsichtig sind, ist es einfach, Optionen mit widersprüchlichen Optionszeichenketten zu definieren:
parser.add_option("-n", "--dry-run", ...)
...
parser.add_option("-n", "--noisy", ...)
(Dies gilt insbesondere, wenn Sie Ihre eigene OptionParser-Unterklasse mit einigen Standardoptionen definiert haben.)
Jedes Mal, wenn Sie eine Option hinzufügen, prüft optparse auf Konflikte mit vorhandenen Optionen. Wenn es welche findet, ruft es den aktuellen Mechanismus zur Konfliktbehandlung auf. Sie können den Mechanismus zur Konfliktbehandlung entweder im Konstruktor einstellen:
parser = OptionParser(..., conflict_handler=handler)
oder mit einem separaten Aufruf:
parser.set_conflict_handler(handler)
Die verfügbaren Konfliktbehandler sind:
"error"(Standard)Optionen-Konflikte als Programmierfehler annehmen und
OptionConflictErrorauslösen."resolve"Optionen-Konflikte intelligent lösen (siehe unten).
Als Beispiel definieren wir einen OptionParser, der Konflikte intelligent löst, und fügen ihm widersprüchliche Optionen hinzu:
parser = OptionParser(conflict_handler="resolve")
parser.add_option("-n", "--dry-run", ..., help="do no harm")
parser.add_option("-n", "--noisy", ..., help="be noisy")
An diesem Punkt erkennt optparse, dass eine zuvor hinzugefügte Option bereits die Optionszeichenkette -n verwendet. Da conflict_handler auf "resolve" gesetzt ist, löst es die Situation, indem es -n aus der Liste der Optionszeichenketten der früheren Option entfernt. Nun ist --dry-run der einzige Weg für den Benutzer, diese Option zu aktivieren. Wenn der Benutzer nach Hilfe fragt, wird die Hilfemeldung dies widerspiegeln:
Options:
--dry-run do no harm
...
-n, --noisy be noisy
Es ist möglich, die Optionszeichenketten einer zuvor hinzugefügten Option so weit zu reduzieren, dass keine mehr übrig sind und der Benutzer keine Möglichkeit hat, diese Option über die Kommandozeile aufzurufen. In diesem Fall entfernt optparse diese Option vollständig, sodass sie weder in der Hilfe noch anderswo erscheint. Weiter mit unserem bestehenden OptionParser:
parser.add_option("--dry-run", ..., help="new dry-run option")
Zu diesem Zeitpunkt ist die ursprüngliche Option -n/--dry-run nicht mehr zugänglich, sodass optparse sie entfernt und diese Hilfe hinterlässt:
Options:
...
-n, --noisy be noisy
--dry-run new dry-run option
Bereinigung¶
OptionParser-Instanzen haben mehrere zyklische Referenzen. Dies sollte für den Garbage Collector von Python kein Problem darstellen, aber Sie können die zyklischen Referenzen explizit aufbrechen, indem Sie destroy() auf Ihrem OptionParser aufrufen, sobald Sie damit fertig sind. Dies ist besonders nützlich in langlebigen Anwendungen, in denen große Objektgraphen von Ihrem OptionParser erreichbar sind.
Andere Methoden¶
OptionParser unterstützt mehrere andere öffentliche Methoden:
- OptionParser.set_usage(usage)¶
Setzt die Nutzungszeichenkette gemäß den Regeln, die oben für das Konstruktor-Schlüsselwortargument
usagebeschrieben wurden. Das Übergeben vonNonesetzt die Standard-Nutzungszeichenkette; verwenden Sieoptparse.SUPPRESS_USAGE, um eine Nutzungsnachricht zu unterdrücken.
- OptionParser.print_usage(file=None)¶
Gibt die Nutzungsnachricht für das aktuelle Programm (
self.usage) an file (Standard ist stdout) aus. Jede Vorkommen der Zeichenkette%proginself.usagewird durch den Namen des aktuellen Programms ersetzt. Tut nichts, wennself.usageleer oder nicht definiert ist.
- OptionParser.get_usage()¶
Dasselbe wie
print_usage(), gibt aber die Nutzungszeichenkette zurück, anstatt sie auszugeben.
- OptionParser.set_defaults(dest=value, ...)¶
Setzt Standardwerte für mehrere Optionsziele gleichzeitig. Die Verwendung von
set_defaults()ist der bevorzugte Weg, um Standardwerte für Optionen festzulegen, da mehrere Optionen sich dasselbe Ziel teilen können. Wenn zum Beispiel mehrere "Modus"-Optionen dasselbe Ziel setzen, kann eine beliebige davon den Standardwert setzen, und die letzte gewinnt.parser.add_option("--advanced", action="store_const", dest="mode", const="advanced", default="novice") # overridden below parser.add_option("--novice", action="store_const", dest="mode", const="novice", default="advanced") # overrides above setting
Um diese Verwirrung zu vermeiden, verwenden Sie
set_defaults().parser.set_defaults(mode="advanced") parser.add_option("--advanced", action="store_const", dest="mode", const="advanced") parser.add_option("--novice", action="store_const", dest="mode", const="novice")
Options-Callbacks¶
Wenn die eingebauten Aktionen und Typen von optparse nicht ganz ausreichen, haben Sie zwei Möglichkeiten: optparse erweitern oder eine Callback-Option definieren. Die Erweiterung von optparse ist allgemeiner, aber für viele einfache Fälle übertrieben. Oft reicht ein einfacher Callback aus.
Es gibt zwei Schritte zur Definition einer Callback-Option:
Definieren Sie die Option selbst mit der Aktion
"callback".Schreiben Sie den Callback; dies ist eine Funktion (oder Methode), die mindestens vier Argumente wie unten beschrieben entgegennimmt.
Definieren einer Callback-Option¶
Wie immer ist der einfachste Weg, eine Callback-Option zu definieren, die Methode OptionParser.add_option() zu verwenden. Abgesehen von action ist das einzige Optionsattribut, das Sie angeben müssen, callback, die aufzurufende Funktion.
parser.add_option("-c", action="callback", callback=my_callback)
callback ist eine Funktion (oder ein anderes aufrufbares Objekt), daher müssen Sie my_callback() bereits definiert haben, wenn Sie diese Callback-Option erstellen. In diesem einfachen Fall weiß optparse nicht einmal, ob -c Argumente erwartet, was normalerweise bedeutet, dass die Option keine Argumente erwartet – die bloße Anwesenheit von -c in der Kommandozeile ist alles, was es wissen muss. Unter bestimmten Umständen möchten Sie jedoch vielleicht, dass Ihr Callback eine beliebige Anzahl von Kommandozeilenargumenten verarbeitet. Hier wird das Schreiben von Callbacks knifflig; es wird später in diesem Abschnitt behandelt.
optparse übergibt immer vier bestimmte Argumente an Ihren Callback, und es übergibt nur zusätzliche Argumente, wenn Sie diese über callback_args und callback_kwargs angeben. Daher ist die minimale Callback-Funktionssignatur:
def my_callback(option, opt, value, parser):
Die vier Argumente eines Callbacks werden unten beschrieben.
Es gibt mehrere andere Optionsattribute, die Sie beim Definieren einer Callback-Option angeben können:
typehat seine übliche Bedeutung: wie bei den Aktionen
"store"oder"append"weist esoptparsean, ein Argument zu verbrauchen und es intypezu konvertieren. Anstatt den/die konvertierten Wert(e) irgendwo zu speichern, übergibtoptparseihn an Ihre Callback-Funktion.nargshat ebenfalls seine übliche Bedeutung: wenn es angegeben ist und > 1 ist, verbraucht
optparsenargsArgumente, von denen jedes intypekonvertierbar sein muss. Es übergibt dann ein Tupel von konvertierten Werten an Ihren Callback.callback_argsein Tupel von zusätzlichen Positionsargumenten, die an den Callback übergeben werden sollen.
callback_kwargsein Wörterbuch von zusätzlichen Schlüsselwortargumenten, die an den Callback übergeben werden sollen.
Wie Callbacks aufgerufen werden¶
Alle Callbacks werden wie folgt aufgerufen:
func(option, opt_str, value, parser, *args, **kwargs)
wobei
Optionist die Option-Instanz, die den Callback aufruft.
opt_strist die Optionszeichenkette, die in der Kommandozeile gesehen wurde und den Callback auslöst. (Wenn eine abgekürzte lange Option verwendet wurde, ist
opt_strdie vollständige, kanonische Optionszeichenkette – z. B. wenn der Benutzer--fooin der Kommandozeile als Abkürzung für--foobareingibt, dann istopt_str"--foobar".)valueist das Argument dieser Option, das in der Kommandozeile gesehen wurde.
optparseerwartet nur dann ein Argument, wenntypegesetzt ist; der Typ vonvalueist der durch den Typ der Option implizierte Typ. Wenntypefür diese OptionNoneist (kein Argument erwartet), dann istvalueNone. Wennnargs> 1 ist, istvalueein Tupel von Werten des entsprechenden Typs.Parserist die OptionParser-Instanz, die alles steuert, hauptsächlich nützlich, da Sie über ihre Instanzattribute auf weitere interessante Daten zugreifen können.
parser.largsdie aktuelle Liste der verbleibenden Argumente, d. h. Argumente, die verarbeitet wurden, aber weder Optionen noch Optionsargumente sind. Fühlen Sie sich frei,
parser.largszu ändern, z. B. indem Sie weitere Argumente hinzufügen. (Diese Liste wird zuargs, dem zweiten Rückgabewert vonparse_args().)parser.rargsdie aktuelle Liste der verbleibenden Argumente, d. h. mit entfernten
opt_strundvalue(falls zutreffend) und nur den nachfolgenden Argumenten. Fühlen Sie sich frei,parser.rargszu ändern, z. B. indem Sie weitere Argumente verarbeiten.parser.valuesdas Objekt, in dem Optionswerte standardmäßig gespeichert werden (eine Instanz von optparse.OptionValues). Dies ermöglicht Callbacks, denselben Mechanismus wie der Rest von
optparsezum Speichern von Optionswerten zu verwenden; Sie müssen sich nicht mit globalen Variablen oder Closures herumschlagen. Sie können auch die Werte von Optionen, die bereits auf der Kommandozeile angetroffen wurden, abrufen oder ändern.
argsist ein Tupel von beliebigen Positionsargumenten, die über das Optionsattribut
callback_argsübergeben wurden.kwargsist ein Wörterbuch von beliebigen Schlüsselwortargumenten, die über
callback_kwargsübergeben wurden.
Fehler in einem Callback auslösen¶
Die Callback-Funktion sollte OptionValueError auslösen, wenn es Probleme mit der Option oder ihren Argumenten gibt. optparse fängt dies ab und beendet das Programm, wobei die von Ihnen angegebene Fehlermeldung nach stderr ausgegeben wird. Ihre Nachricht sollte klar, prägnant, korrekt sein und die fragliche Option erwähnen. Andernfalls wird es dem Benutzer schwerfallen zu verstehen, was er falsch gemacht hat.
Callback-Beispiel 1: trivialer Callback¶
Hier ist ein Beispiel für eine Callback-Option, die keine Argumente entgegennimmt und einfach aufzeichnet, dass die Option gesehen wurde:
def record_foo_seen(option, opt_str, value, parser):
parser.values.saw_foo = True
parser.add_option("--foo", action="callback", callback=record_foo_seen)
Natürlich könnten Sie das auch mit der Aktion "store_true" tun.
Callback-Beispiel 2: Reihenfolge der Optionen prüfen¶
Hier ist ein etwas interessanteres Beispiel: Zeichnen Sie die Tatsache auf, dass -a gesehen wurde, aber schlagen Sie fehl, wenn es nach -b in der Kommandozeile kommt:
def check_order(option, opt_str, value, parser):
if parser.values.b:
raise OptionValueError("can't use -a after -b")
parser.values.a = 1
...
parser.add_option("-a", action="callback", callback=check_order)
parser.add_option("-b", action="store_true", dest="b")
Callback-Beispiel 3: Reihenfolge der Optionen prüfen (verallgemeinert)¶
Wenn Sie diesen Callback für mehrere ähnliche Optionen wiederverwenden möchten (ein Flag setzen, aber fehlschlagen, wenn -b bereits gesehen wurde), muss er etwas überarbeitet werden: die Fehlermeldung und das Flag, das er setzt, müssen verallgemeinert werden.
def check_order(option, opt_str, value, parser):
if parser.values.b:
raise OptionValueError("can't use %s after -b" % opt_str)
setattr(parser.values, option.dest, 1)
...
parser.add_option("-a", action="callback", callback=check_order, dest='a')
parser.add_option("-b", action="store_true", dest="b")
parser.add_option("-c", action="callback", callback=check_order, dest='c')
Callback-Beispiel 4: beliebige Bedingung prüfen¶
Natürlich könnten Sie jede Bedingung dort einfügen – Sie sind nicht darauf beschränkt, die Werte bereits definierter Optionen zu überprüfen. Zum Beispiel, wenn Sie Optionen haben, die nicht aufgerufen werden sollten, wenn der Mond voll ist, müssen Sie nur Folgendes tun:
def check_moon(option, opt_str, value, parser):
if is_moon_full():
raise OptionValueError("%s option invalid when moon is full"
% opt_str)
setattr(parser.values, option.dest, 1)
...
parser.add_option("--foo",
action="callback", callback=check_moon, dest="foo")
(Die Definition von is_moon_full() ist dem Leser als Übung überlassen.)
Callback-Beispiel 5: feste Argumente¶
Die Dinge werden etwas interessanter, wenn Sie Callback-Optionen definieren, die eine feste Anzahl von Argumenten erwarten. Die Angabe, dass eine Callback-Option Argumente erwartet, ähnelt der Definition einer Option vom Typ "store" oder "append": Wenn Sie type definieren, erwartet die Option ein Argument, das in diesen Typ konvertierbar sein muss; wenn Sie zusätzlich nargs definieren, erwartet die Option nargs Argumente.
Hier ist ein Beispiel, das nur die Standardaktion "store" emuliert:
def store_value(option, opt_str, value, parser):
setattr(parser.values, option.dest, value)
...
parser.add_option("--foo",
action="callback", callback=store_value,
type="int", nargs=3, dest="foo")
Beachten Sie, dass optparse sich um das Verbrauchen von 3 Argumenten und deren Konvertierung in Ganzzahlen kümmert; Sie müssen nur damit arbeiten. (Oder was auch immer; offensichtlich brauchen Sie für dieses Beispiel keinen Callback.)
Callback-Beispiel 6: variable Argumente¶
Die Dinge werden kompliziert, wenn Sie möchten, dass eine Option eine variable Anzahl von Argumenten erwartet. In diesem Fall müssen Sie einen Callback schreiben, da optparse dafür keine eingebauten Funktionen bietet. Und Sie müssen sich mit bestimmten Feinheiten des konventionellen Unix-Kommandozeilen-Parsings auseinandersetzen, die optparse normalerweise für Sie erledigt. Insbesondere sollten Callbacks die konventionellen Regeln für nackte -- und - Argumente implementieren:
Entweder
--oder-können Optionsargumente sein.Ein nacktes
--(wenn es nicht das Argument für eine Option ist): beendet die Verarbeitung der Kommandozeile und verwirft die--.bare
-(wenn nicht Argument für eine Option): Befehlszeilenverarbeitung stoppen, aber-beibehalten (anparser.largsanhängen)
Wenn Sie eine Option wünschen, die eine variable Anzahl von Argumenten nimmt, gibt es mehrere subtile, knifflige Probleme zu beachten. Die genaue Implementierung, die Sie wählen, basiert darauf, welche Kompromisse Sie für Ihre Anwendung eingehen wollen (weshalb optparse diese Art von Sache nicht direkt unterstützt).
Dennoch, hier ist ein Versuch für einen Callback für eine Option mit variablen Argumenten
def vararg_callback(option, opt_str, value, parser):
assert value is None
value = []
def floatable(str):
try:
float(str)
return True
except ValueError:
return False
for arg in parser.rargs:
# stop on --foo like options
if arg[:2] == "--" and len(arg) > 2:
break
# stop on -a, but not on -3 or -3.0
if arg[:1] == "-" and len(arg) > 1 and not floatable(arg):
break
value.append(arg)
del parser.rargs[:len(value)]
setattr(parser.values, option.dest, value)
...
parser.add_option("-c", "--callback", dest="vararg_attr",
action="callback", callback=vararg_callback)
Erweiterung von optparse¶
Da die beiden Hauptfaktoren, die bestimmen, wie optparse Befehlszeilenoptionen interpretiert, die Aktion und der Typ jeder Option sind, ist die wahrscheinlichste Richtung der Erweiterung, neue Aktionen und neue Typen hinzuzufügen.
Hinzufügen neuer Typen¶
Um neue Typen hinzuzufügen, müssen Sie Ihre eigene Unterklasse der optparse-Klasse Option definieren. Diese Klasse hat einige Attribute, die die Typen von optparse definieren: TYPES und TYPE_CHECKER.
- Option.TYPES¶
Ein Tupel von Typnamen; in Ihrer Unterklasse definieren Sie einfach ein neues Tupel
TYPES, das auf dem Standard aufbaut.
- Option.TYPE_CHECKER¶
Ein Dictionary, das Typnamen auf Typüberprüfungsfunktionen abbildet. Eine Typüberprüfungsfunktion hat die folgende Signatur
def check_mytype(option, opt, value)
wobei
optioneineOption-Instanz ist,optein Optionsstring ist (z. B.-f) undvalueder String von der Befehlszeile ist, der überprüft und in Ihren gewünschten Typ konvertiert werden muss.check_mytype()sollte ein Objekt des hypothetischen Typsmytypezurückgeben. Der von einer Typüberprüfungsfunktion zurückgegebene Wert wird in der OptionValues-Instanz landen, die vonOptionParser.parse_args()zurückgegeben wird, oder alsvalue-Parameter an einen Callback übergeben.Ihre Typüberprüfungsfunktion sollte
OptionValueErrorauslösen, wenn sie auf Probleme stößt.OptionValueErrornimmt ein einzelnes String-Argument, das unverändert an dieerror()-Methode vonOptionParserübergeben wird, die wiederum den Programmnamen und den String"error:"voranstellt und alles nach stderr ausgibt, bevor der Prozess beendet wird.
Hier ist ein albernes Beispiel, das das Hinzufügen eines "complex"-Optionstyps zum Parsen von komplexen Zahlen im Python-Stil von der Befehlszeile aus demonstriert. (Das ist noch alberner als früher, weil optparse 1.3 die integrierte Unterstützung für komplexe Zahlen hinzugefügt hat, aber egal.)
Zuerst die notwendigen Importe
from copy import copy
from optparse import Option, OptionValueError
Sie müssen zuerst Ihren Typüberprüfer definieren, da er später referenziert wird (im TYPE_CHECKER-Klassenattribut Ihrer Option-Unterklasse)
def check_complex(option, opt, value):
try:
return complex(value)
except ValueError:
raise OptionValueError(
"option %s: invalid complex value: %r" % (opt, value))
Schließlich die Option-Unterklasse
class MyOption (Option):
TYPES = Option.TYPES + ("complex",)
TYPE_CHECKER = copy(Option.TYPE_CHECKER)
TYPE_CHECKER["complex"] = check_complex
(Wenn wir keine copy() von Option.TYPE_CHECKER machen würden, würden wir das TYPE_CHECKER-Attribut der Option-Klasse von optparse modifizieren. Da dies Python ist, hält Sie nichts davon ab, außer guten Manieren und gesundem Menschenverstand.)
Das ist alles! Jetzt können Sie ein Skript schreiben, das den neuen Optionstyp wie jedes andere optparse-basierte Skript verwendet, mit der Ausnahme, dass Sie Ihren OptionParser anweisen müssen, MyOption anstelle von Option zu verwenden
parser = OptionParser(option_class=MyOption)
parser.add_option("-c", type="complex")
Alternativ können Sie Ihre eigene Optionsliste erstellen und diese an OptionParser übergeben. Wenn Sie add_option() nicht wie oben gezeigt verwenden, müssen Sie OptionParser nicht mitteilen, welche Option-Klasse verwendet werden soll
option_list = [MyOption("-c", action="store", type="complex", dest="c")]
parser = OptionParser(option_list=option_list)
Hinzufügen neuer Aktionen¶
Das Hinzufügen neuer Aktionen ist etwas kniffliger, da Sie verstehen müssen, dass optparse zwei Klassifizierungen für Aktionen hat
- „store“-Aktionen
Aktionen, die dazu führen, dass
optparseeinen Wert in einem Attribut der aktuellen OptionValues-Instanz speichert; diese Optionen erfordern, dass dem Option-Konstruktor eindest-Attribut übergeben wird.- „typed“-Aktionen
Aktionen, die einen Wert von der Befehlszeile entgegennehmen und erwarten, dass dieser einen bestimmten Typ hat; oder besser gesagt, einen String, der in einen bestimmten Typ konvertiert werden kann. Diese Optionen erfordern ein
type-Attribut für den Option-Konstruktor.
Dies sind überlappende Mengen: einige Standard-„store“-Aktionen sind "store", "store_const", "append" und "count", während die Standard-„typed“-Aktionen "store", "append" und "callback" sind.
Wenn Sie eine Aktion hinzufügen, müssen Sie sie kategorisieren, indem Sie sie in mindestens einem der folgenden Klassenattribute von Option auflisten (alle sind Listen von Strings)
- Option.ACTIONS¶
Alle Aktionen müssen in ACTIONS aufgeführt sein.
- Option.STORE_ACTIONS¶
„store“-Aktionen werden zusätzlich hier aufgeführt.
- Option.TYPED_ACTIONS¶
„typed“-Aktionen werden zusätzlich hier aufgeführt.
- Option.ALWAYS_TYPED_ACTIONS¶
Aktionen, die immer einen Typ benötigen (d. h. deren Optionen immer einen Wert nehmen), sind hier zusätzlich aufgeführt. Der einzige Effekt davon ist, dass
optparseden Standardtyp"string"zu Optionen ohne expliziten Typ zuweist, deren Aktion inALWAYS_TYPED_ACTIONSaufgeführt ist.
Um Ihre neue Aktion tatsächlich zu implementieren, müssen Sie die Methode take_action() von Option überschreiben und einen Fall hinzufügen, der Ihre Aktion erkennt.
Zum Beispiel fügen wir eine "extend"-Aktion hinzu. Diese ähnelt der Standard-"append"-Aktion, aber anstatt einen einzelnen Wert von der Befehlszeile zu nehmen und ihn an eine vorhandene Liste anzuhängen, nimmt "extend" mehrere Werte in einem einzigen Komma-getrennten String und erweitert eine vorhandene Liste damit. Das heißt, wenn --names eine "extend"-Option vom Typ "string" ist, würde die Befehlszeile
--names=foo,bar --names blah --names ding,dong
zu einer Liste führen
["foo", "bar", "blah", "ding", "dong"]
Wieder definieren wir eine Unterklasse von Option
class MyOption(Option):
ACTIONS = Option.ACTIONS + ("extend",)
STORE_ACTIONS = Option.STORE_ACTIONS + ("extend",)
TYPED_ACTIONS = Option.TYPED_ACTIONS + ("extend",)
ALWAYS_TYPED_ACTIONS = Option.ALWAYS_TYPED_ACTIONS + ("extend",)
def take_action(self, action, dest, opt, value, values, parser):
if action == "extend":
lvalue = value.split(",")
values.ensure_value(dest, []).extend(lvalue)
else:
Option.take_action(
self, action, dest, opt, value, values, parser)
Bemerkenswerte Merkmale
"extend"erwartet sowohl einen Wert auf der Befehlszeile als auch speichert diesen Wert irgendwo, daher gehört er sowohl zuSTORE_ACTIONSals auch zuTYPED_ACTIONS.Um sicherzustellen, dass
optparseden Standardtyp"string"für"extend"-Aktionen zuweist, nehmen wir die"extend"-Aktion auch inALWAYS_TYPED_ACTIONSauf.MyOption.take_action()implementiert nur diese eine neue Aktion und gibt die Kontrolle anOption.take_action()für die Standard-optparse-Aktionen zurück.valuesist eine Instanz der Klasse optparse_parser.Values, die die sehr nützliche Methodeensure_value()bereitstellt.ensure_value()ist im Wesentlichengetattr()mit einem Sicherheitsventil; sie wird aufgerufen alsvalues.ensure_value(attr, value)
Wenn das Attribut
attrvonvaluesnicht existiert oderNoneist, dann setzt ensure_value() es zuerst aufvalueund gibt dannvaluezurück. Dies ist sehr nützlich für Aktionen wie"extend","append"und"count", die alle Daten in einer Variablen sammeln und erwarten, dass diese Variable einen bestimmten Typ hat (eine Liste für die ersten beiden, eine Ganzzahl für letztere). Die Verwendung vonensure_value()bedeutet, dass Skripte, die Ihre Aktion verwenden, sich keine Sorgen machen müssen, einen Standardwert für die betreffenden Optionsziele festzulegen; sie können den Standard einfach aufNonebelassen, undensure_value()kümmert sich darum, ihn richtig zu setzen, wenn er benötigt wird.
Ausnahmen¶
- exception optparse.OptionError¶
Ausgelöst, wenn eine
Option-Instanz mit ungültigen oder inkonsistenten Argumenten erstellt wird.
- exception optparse.OptionConflictError¶
Ausgelöst, wenn widersprüchliche Optionen zu einem
OptionParserhinzugefügt werden.
- exception optparse.OptionValueError¶
Ausgelöst, wenn ein ungültiger Optionswert auf der Befehlszeile gefunden wird.
- exception optparse.BadOptionError¶
Ausgelöst, wenn eine ungültige Option auf der Befehlszeile übergeben wird.
- exception optparse.AmbiguousOptionError¶
Ausgelöst, wenn eine mehrdeutige Option auf der Befehlszeile übergeben wird.