Vergleich von Kommandozeilen-Parsing-Bibliotheken
Vergleich von Kommandozeilen-Parsing-Bibliotheken
HINWEIS: Diese Seite existiert nur zu historischen Zwecken. Die getopt-sig ist eingestellt, und Optik wurde (als optparse) in Python 2.3 in die Python-Standardbibliothek aufgenommen. (Es wurde im November 2002 in den CVS-Baum von Python eingecheckt und erstmals im Juli 2003 veröffentlicht.)
Seit ich Optik für die Python-Standardbibliothek vorgeschlagen habe, sind einige andere Kommandozeilen-Parsing-Bibliotheken aufgetaucht. Ich versuche, sie zu bewerten, indem ich dieselbe reale Kommandozeilenschnittstelle mit mehreren verschiedenen Bibliotheken implementiere. Derzeit existieren Implementierungen für
- Greg Wards (das bin ich) Optik
- Russ Cox' Iterator-Schnittstelle (ArgParser)
- Albert Hofkamps argtools (Seite nicht mehr verfügbar)
- David Boddies CMDSyntax (Seite nicht mehr verfügbar)
Benutzeroberfläche
Die von mir gewählte Schnittstelle ist die meines ripoff CD-Ripping-Skripts. Die Hauptmerkmale dieser Schnittstelle sind
- eine unkomplizierte, Standard-Schnittstelle (keine komplizierten Interaktionen zwischen Optionen)
- eine respektable Anzahl (ungefähr 17) von Optionen – genug, dass eine Art High-Level-Kommandozeilen-Parsing-Hilfe wirklich nützlich ist, aber nicht so viele, dass es ewig dauern würde, die Schnittstelle mehrmals neu zu implementieren
- eine gute Vielfalt an Optionstypen und Aktionen (um Optiks Terminologie zu verwenden) (aber nichts wirklich Schrulliges oder Ungewöhnliches)
- es werden keine Positionsargumente erwartet oder erlaubt – d. h. alles, was Ripoff wissen muss, kann aus Kommandozeilenoptionen übernommen werden.
Um die Dinge konkret zu halten, hier ist Ripoffs Hilfetext (wie von Optik generiert).
Eine Schwäche von Ripoffs Kommandozeilenschnittstelle ist, dass mehrere Flag-Optionen kein negatives Gegenstück haben: z. B. gibt es eine --keep-tmp-Option, aber keine --no-keep-tmp. Diese Art von Sache ist in der realen Welt wirklich notwendig, wo der Standardwert eines Programms (in diesem Fall no-keep-tmp) durch eine Konfigurationsdatei überschrieben und dann auf der Kommandozeile erneut überschrieben werden kann. Diese Schwäche spiegelt sich derzeit in allen drei meiner Test-Neuimplementierungen wider.
Interne Schnittstellen
Intern arbeitet Ripoff, indem es ein einzelnes Objekt weitergibt, das alle Werte von der Kommandozeile enthält. Z. B. befindet sich die vom Benutzer ausgewählte Ausführlichkeitsstufe in options.verbose, und die CD-ROM-Gerätedatei befindet sich in options.device. Es gibt nicht ganz so viele Optionswerte wie Optionen: Die Option -v/--verbose und -q/--quiet aktualisieren beide options.verbose, und -p/--use-pipes und -f/--use-files aktualisieren beide das Flag options.use_pipes.
Ich habe dies in allen meinen Test-Neuimplementierungen beibehalten. Dies kommt Optik zugute (da es Optionswerte bereits in einem dedizierten Objekt speichert); hat nicht viel Einfluss auf die Iterator-Version (es bedeutet nur etwas mehr Tipparbeit); und es lässt argtools schlecht aussehen, da ich alle meine Optionswerte explizit vom Parser-Objekt auf mein dediziertes Optionswerte-Objekt kopieren muss.
Und nun, meine Damen und Herren...
Genug der Verzögerung, weiter geht's! Zuerst einige einfache Statistiken über die drei Neuimplementierungen| Bibliothek | Gesamter Code[1] | Code (ohne Hilfe)[2] |
|---|---|---|
| Optik | 62 | 34 |
| Iterator | 112 | 73 |
| argtools | 108 | 69 |
- wie berichtet von Dinu Ghermans pycount – d. h. dies sind Zeilen echten Codes, ohne Leerzeilen, Kommentare oder Docstrings (aber mit Zählung von Literal-Strings, wie Hilfe- und Nutztexten)
- d. h. mit entferntem explizitem Hilfetext. Für ArgParser und argtools ist dies nur ein großer Literal-String, da diese Bibliotheken keine automatische Hilfegenerierung durchführen. Für Optik bedeutet dies lediglich das Entfernen des
help-Parameters von jeder Option; selbst wenn dieser Options-spezifische Hilfetext entfernt wird, bietet Optik immer noch eine --help-Option, die anzeigt, welche Optionen verfügbar sind
Aber wie Mark Twain sagte: Es gibt Lügen, verfluchte Lügen und Statistiken. Sehen wir uns also etwas Code an.
- ripoff_optik.py ist die mit Optik implementierte Kommandozeilenschnittstelle von Ripoff (natürlich direkt aus dem Quellcode von Ripoff geschnippselt)
- ripoff_iterator.py ist die Neuimplementierung unter Verwendung der Iterator-Schnittstelle von Russ Cox
- ripoff_argtools.py ist die Neuimplementierung unter Verwendung von Albert Hofkamps argtools
- der Beispielcode für CMDSyntax, bereitgestellt von David Boddie (Seite nicht mehr verfügbar)
Wenn Sie tatsächlich eine dieser Implementierungen ausführen möchten, ohne sie zu modifizieren, müssen Sie den Ripoff-Quellcode aus seinem CVS-Repository beziehen. Dies liegt daran, dass ich 1) eine realistische --version-Option (die ripoff.__version__ verwendet) und 2) realistische Hilfe für die -d/--device-Option (die auf dem ripoff.cdrom-Erweiterungsmodul basiert, insbesondere der Funktion get_default_device()) wollte. Der eigentliche Zweck hier ist jedoch, den Code zu untersuchen, nicht ihn auszuführen.
