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 C getopt API angelehnt ist. Seit vor der ersten Python 1.0-Version in der Standardbibliothek enthalten.

  • optparse: ein deklarativer Ersatz für getopt, 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 zu optparse, 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 optparse und möchte keine subtilen Verhaltensänderungen riskieren, die bei der Migration zu argparse auftreten können

  • die 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 argparse dies 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 argparse nicht unterstützt, aber das sich mithilfe der von optparse angebotenen 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 -v ergibt output="-v" und verbose=False bei Verwendung von optparse, aber einen Nutzungsfehler bei argparse (der beanstandet, dass kein Wert für -o/--output angegeben wurde, da -v als Verbositätsflag interpretiert wird)

  • ähnlich ergibt die Angabe von -o -- output="--" und args=() bei Verwendung von optparse, aber einen Nutzungsfehler bei argparse (der ebenfalls beanstandet, dass kein Wert für -o/--output angegeben wurde, da -- als Beendigung der Optionsverarbeitung und Behandlung aller verbleibenden Werte als Positionsargumente interpretiert wird)

  • die Angabe von -o=foo ergibt output="=foo" bei Verwendung von optparse, aber output="foo" mit argparse (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() oder execv() übergeben wird. In Python sind Argumente Elemente von sys.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 von sys.argv[1:] oder einer anderen Liste, die als Ersatz für sys.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. -x oder -F. Außerdem erlaubt die traditionelle Unix-Syntax, mehrere Optionen zu einem einzigen Argument zusammenzufassen, z. B. -x -F ist äquivalent zu -xF. Das GNU-Projekt führte -- gefolgt von einer Reihe von durch Bindestriche getrennten Wörtern ein, z. B. --file oder --dry-run. Dies sind die einzigen beiden Optionssyntaxen, die von optparse bereitgestellt 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, +rgb

  • ein Schrägstrich gefolgt von einem Buchstaben, oder einigen Buchstaben, oder einem Wort, z. B. /f, /file

Diese Optionssyntaxen werden von optparse nicht 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 optparse kö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 -a ein optionales Argument nimmt und -b eine andere Option ist, wie interpretieren wir dann -ab? Aufgrund dieser Mehrdeutigkeit unterstützt optparse diese 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. optparse hindert 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 --file ein einzelnes String-Argument nimmt, dann ist options.file der vom Benutzer bereitgestellte Dateiname oder None, wenn der Benutzer diese Option nicht angegeben hat

  • args, 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.const voreingestellt 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"
    

    optparse erweitert %prog in der Nutzungszeichenfolge zum Namen des aktuellen Programms, d. h. zu os.path.basename(sys.argv[0]). Die erweiterte Zeichenfolge wird dann vor der detaillierten Optionshilfe ausgegeben.

    Wenn Sie keine Nutzungszeichenfolge angeben, verwendet optparse einen 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 – optparse kü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 konvertiert optparse den Namen der Zielvariablen in Großbuchstaben und verwendet diesen für die Metavariable. Manchmal ist das nicht gewünscht – zum Beispiel setzt die Option --filename explizit metavar="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 FILE und 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 %default in der Hilfezeichenfolge enthalten – optparse ersetzt es durch str() des Standardwerts der Option. Wenn eine Option keinen Standardwert hat (oder der Standardwert None ist), expandiert %default zu none.

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 OptionGroup zurück, zu der die kurze oder lange Optionszeichenfolge opt_str gehört (z. B. '-o' oder '--option'). Wenn keine solche OptionGroup vorhanden ist, wird None zurü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 bei print_usage() wird jede Vorkommens von %prog in self.version durch den Namen des aktuellen Programms ersetzt. Es tut nichts, wenn self.version leer 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 optparse die Nutzungszeichenfolge ausgibt, erweitert es %prog zu os.path.basename(sys.argv[0]) (oder zu prog, wenn Sie dieses Schlüsselwortargument übergeben haben). Um eine Nutzungsnachricht zu unterdrücken, übergeben Sie den speziellen Wert optparse.SUPPRESS_USAGE.

option_list (Standard: [])

Eine Liste von Option-Objekten, um den Parser zu füllen. Die Optionen in option_list werden nach allen Optionen in standard_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 Parsers add_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 version angeben, fügt optparse automatisch eine Versionsoption mit der einzelnen Optionszeichenfolge --version hinzu. Der Unterstring %prog wird genauso erweitert wie für usage.

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. optparse formatiert diesen Absatz neu, um ihn an die aktuelle Terminalbreite anzupassen, und gibt ihn aus, wenn der Benutzer Hilfe anfordert (nach usage, aber vor der Liste der Optionen).

formatter (Standard: ein neues IndentedHelpFormatter)

Eine Instanz von optparse.HelpFormatter, die zum Drucken von Hilfetexten verwendet wird. optparse bietet zwei konkrete Klassen für diesen Zweck: IndentedHelpFormatter und TitledHelpFormatter.

add_help_option (Standard: True)

Wenn wahr, fügt optparse eine Hilfeoption (mit den Optionszeichenfolgen -h und --help) zum Parser hinzu.

prog

Die Zeichenfolge, die zum Erweitern von %prog in usage und version anstelle von os.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öst optparse eine OptionError-Ausnahme aus, die Ihren Fehler erklärt.

Die Aktion einer Option bestimmt, was optparse tut, wenn es diese Option auf der Kommandozeile findet. Die Standard-Option-Aktionen, die fest in optparse eingebaut sind, sind

"store"

speichert das Argument dieser Option (Standard)

"store_const"

Speichern eines konstanten Werts, der über Option.const voreingestellt 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.const voreingestellt 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-Attribute type und dest angeben; 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 von OptionParser.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ür OptionParser ü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 optparse mit, wohin es schreiben soll: dest nennt ein Attribut des options-Objekts, das optparse beim 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 type konsumiert werden sollen, wenn diese Option gesehen wird. Wenn > 1, speichert optparse ein Tupel von Werten in dest.

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 Sonderwert optparse.SUPPRESS_HELP.

Option.metavar

(Standard: abgeleitet von Options-Strings)

Platzhalter für das/die Options-Argument(e), das/die beim Drucken des Hilfetextes verwendet werden soll(en). Siehe Abschnitt Tutorial für ein Beispiel.

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äß type in einen Wert konvertiert und in dest gespeichert wird. Wenn nargs > 1, werden mehrere Argumente von der Kommandozeile konsumiert; alle werden gemäß type konvertiert und als Tupel in dest gespeichert. Siehe den Abschnitt Standard-Option-Typen.

    Wenn choices angegeben ist (eine Liste oder ein Tupel von Zeichenketten), ist der Standardtyp "choice".

    Wenn type nicht angegeben ist, ist der Standard "string".

    Wenn dest nicht angegeben ist, leitet optparse ein Ziel vom ersten langen Options-String ab (z. B. --foo-bar impliziert foo_bar). Wenn keine langen Options-Strings vorhanden sind, leitet optparse ein Ziel vom ersten kurzen Options-String ab (z. B. -f impliziert f).

    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
    

    optparse setzt

    options.f = "foo.txt"
    options.point = (1.0, -3.5, 4.0)
    options.f = "bar.txt"
    
  • "store_const" [erforderlich: const; relevant: dest]

    Der Wert const wird in dest gespeichert.

    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 --noisy gesehen wird, setzt optparse

    options.verbose = 2
    
  • "store_true" [relevant: dest]

    Ein Sonderfall von "store_const", der True nach dest speichert.

  • "store_false" [relevant: dest]

    Wie "store_true", aber speichert False.

    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 dest angehängt wird. Wenn kein Standardwert für dest angegeben ist, wird eine leere Liste automatisch erstellt, wenn optparse diese Option zum ersten Mal auf der Kommandozeile findet. Wenn nargs > 1, werden mehrere Argumente konsumiert und ein Tupel der Länge nargs an dest angehängt.

    Die Standardwerte für type und dest sind dieselben wie für die Aktion "store".

    Beispiel

    parser.add_option("-t", "--tracks", action="append", type="int")
    

    Wenn -t3 auf der Kommandozeile gesehen wird, führt optparse das Äquivalent von

    options.tracks = []
    options.tracks.append(int("3"))
    

    Wenn, ein wenig später, --tracks=4 gesehen wird, tut es

    options.tracks.append(int("4"))
    

    Die Aktion append ruft die Methode append auf dem aktuellen Wert der Option auf. Das bedeutet, dass jeder angegebene Standardwert eine append-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 Wert const wird an dest angehängt; wie bei "append", hat dest standardmäßig None, und eine leere Liste wird automatisch erstellt, wenn die Option zum ersten Mal angetroffen wird.

  • "count" [relevant: dest]

    Inkrementiert die Ganzzahl, die unter dest gespeichert ist. Wenn kein Standardwert angegeben ist, wird dest auf Null gesetzt, bevor es beim ersten Mal inkrementiert wird.

    Beispiel

    parser.add_option("-v", action="count", dest="verbosity")
    

    Wenn -v zum ersten Mal auf der Kommandozeile gesehen wird, macht optparse das Äquivalent von

    options.verbosity = 0
    options.verbosity += 1
    

    Jede nachfolgendeoccurrence von -v führt zu

    options.verbosity += 1
    
  • "callback" [erforderlich: callback; relevant: type, nargs, callback_args, callback_kwargs]

    Ruft die Funktion auf, die von callback angegeben wird, die aufgerufen wird als

    func(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 der help-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 Sonderwert optparse.SUPPRESS_HELP.

    optparse fügt automatisch eine help-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 optparse entweder -h oder --help in der Kommandozeile sieht, gibt es eine ähnliche Hilfemeldung wie die folgende an stdout aus (vorausgesetzt sys.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 optparse Ihren Prozess mit sys.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 Argument version dem Konstruktor des OptionParser übergeben wurde. Wie bei help-Optionen werden Sie selten version-Optionen erstellen, da optparse diese 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 0x beginnt, wird sie als Hexadezimalzahl geparst.

  • Wenn die Zahl mit 0 beginnt, wird sie als Oktalzahl geparst.

  • Wenn die Zahl mit 0b beginnt, 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:

args

die zu verarbeitende Liste von Argumenten (Standard: sys.argv[1:])

Werte

ein Values-Objekt zum Speichern von Optionsargumenten (Standard: eine neue Instanz von Values) – wenn Sie ein vorhandenes Objekt übergeben, werden die Standardwerte der Optionen nicht darauf initialisiert

und der Rückgabewert ist ein Paar (options, args), wobei

options

dasselbe Objekt, das als values übergeben wurde, oder die von optparse erstellte optparse.Values-Instanz

args

die 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 -a und -b einfache Optionen sind, die keine Argumente nehmen, akzeptiert optparse normalerweise 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 True zurück, wenn der OptionParser eine Option mit der Optionszeichenkette opt_str hat (z. B. -q oder --verbose).

OptionParser.remove_option(opt_str)

Wenn der OptionParser eine 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 diesem OptionParser gehört, wird ValueError ausgelö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 OptionConflictError auslö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 usage beschrieben wurden. Das Übergeben von None setzt die Standard-Nutzungszeichenkette; verwenden Sie optparse.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 %prog in self.usage wird durch den Namen des aktuellen Programms ersetzt. Tut nichts, wenn self.usage leer 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:

type

hat seine übliche Bedeutung: wie bei den Aktionen "store" oder "append" weist es optparse an, ein Argument zu verbrauchen und es in type zu konvertieren. Anstatt den/die konvertierten Wert(e) irgendwo zu speichern, übergibt optparse ihn an Ihre Callback-Funktion.

nargs

hat ebenfalls seine übliche Bedeutung: wenn es angegeben ist und > 1 ist, verbraucht optparse nargs Argumente, von denen jedes in type konvertierbar sein muss. Es übergibt dann ein Tupel von konvertierten Werten an Ihren Callback.

callback_args

ein Tupel von zusätzlichen Positionsargumenten, die an den Callback übergeben werden sollen.

callback_kwargs

ein 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

Option

ist die Option-Instanz, die den Callback aufruft.

opt_str

ist die Optionszeichenkette, die in der Kommandozeile gesehen wurde und den Callback auslöst. (Wenn eine abgekürzte lange Option verwendet wurde, ist opt_str die vollständige, kanonische Optionszeichenkette – z. B. wenn der Benutzer --foo in der Kommandozeile als Abkürzung für --foobar eingibt, dann ist opt_str "--foobar".)

value

ist das Argument dieser Option, das in der Kommandozeile gesehen wurde. optparse erwartet nur dann ein Argument, wenn type gesetzt ist; der Typ von value ist der durch den Typ der Option implizierte Typ. Wenn type für diese Option None ist (kein Argument erwartet), dann ist value None. Wenn nargs > 1 ist, ist value ein Tupel von Werten des entsprechenden Typs.

Parser

ist die OptionParser-Instanz, die alles steuert, hauptsächlich nützlich, da Sie über ihre Instanzattribute auf weitere interessante Daten zugreifen können.

parser.largs

die aktuelle Liste der verbleibenden Argumente, d. h. Argumente, die verarbeitet wurden, aber weder Optionen noch Optionsargumente sind. Fühlen Sie sich frei, parser.largs zu ändern, z. B. indem Sie weitere Argumente hinzufügen. (Diese Liste wird zu args, dem zweiten Rückgabewert von parse_args().)

parser.rargs

die aktuelle Liste der verbleibenden Argumente, d. h. mit entfernten opt_str und value (falls zutreffend) und nur den nachfolgenden Argumenten. Fühlen Sie sich frei, parser.rargs zu ändern, z. B. indem Sie weitere Argumente verarbeiten.

parser.values

das Objekt, in dem Optionswerte standardmäßig gespeichert werden (eine Instanz von optparse.OptionValues). Dies ermöglicht Callbacks, denselben Mechanismus wie der Rest von optparse zum 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.

args

ist ein Tupel von beliebigen Positionsargumenten, die über das Optionsattribut callback_args übergeben wurden.

kwargs

ist 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 (an parser.largs anhä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 option eine Option-Instanz ist, opt ein Optionsstring ist (z. B. -f) und value der String von der Befehlszeile ist, der überprüft und in Ihren gewünschten Typ konvertiert werden muss. check_mytype() sollte ein Objekt des hypothetischen Typs mytype zurückgeben. Der von einer Typüberprüfungsfunktion zurückgegebene Wert wird in der OptionValues-Instanz landen, die von OptionParser.parse_args() zurückgegeben wird, oder als value-Parameter an einen Callback übergeben.

Ihre Typüberprüfungsfunktion sollte OptionValueError auslösen, wenn sie auf Probleme stößt. OptionValueError nimmt ein einzelnes String-Argument, das unverändert an die error()-Methode von OptionParser ü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 optparse einen Wert in einem Attribut der aktuellen OptionValues-Instanz speichert; diese Optionen erfordern, dass dem Option-Konstruktor ein dest-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 optparse den Standardtyp "string" zu Optionen ohne expliziten Typ zuweist, deren Aktion in ALWAYS_TYPED_ACTIONS aufgefü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 zu STORE_ACTIONS als auch zu TYPED_ACTIONS.

  • Um sicherzustellen, dass optparse den Standardtyp "string" für "extend"-Aktionen zuweist, nehmen wir die "extend"-Aktion auch in ALWAYS_TYPED_ACTIONS auf.

  • MyOption.take_action() implementiert nur diese eine neue Aktion und gibt die Kontrolle an Option.take_action() für die Standard-optparse-Aktionen zurück.

  • values ist eine Instanz der Klasse optparse_parser.Values, die die sehr nützliche Methode ensure_value() bereitstellt. ensure_value() ist im Wesentlichen getattr() mit einem Sicherheitsventil; sie wird aufgerufen als

    values.ensure_value(attr, value)
    

    Wenn das Attribut attr von values nicht existiert oder None ist, dann setzt ensure_value() es zuerst auf value und gibt dann value zurü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 von ensure_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 auf None belassen, und ensure_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 OptionParser hinzugefü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.