Verarbeitung von Parametern für die Kommandozeile

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
grubenfox
User
Beiträge: 433
Registriert: Freitag 2. Dezember 2022, 15:49

mal so ein paar Links...
https://realpython.com/command-line-int ... -argparse/
In der Python-Standard-Lib scheint aktuell argparse das Mittel der Wahl zu sein. Es gebe noch optparse, aber das ist im Status deprecated. (noch ältere Module lass ich mal außen vor)

Außerhalb der Standard-Lib gebe es dann z.b. "click", welches intern auf optparse basiert:
https://click.palletsprojects.com/en/8.1.x/why/

Wenn ich jetzt noch eine Suchmaschine anwerfen würde, dann würde ich noch weitere Namen von passenden Modulen finden. Aber ich suche keine Namen, sondern Erfahrungsberichte...
Was nehmt ihr für die Behandlung von Kommandozeilenparametern, welche Module taugen was, welche nicht? Zusatzfrage: bei welchen Modulen lassen sich die Hilfetexte (die vom Modul selbst geliefert werden und wahrscheinlich Englisch sind) problemlos in andere Sprachen übersetzen?

Was argparse betrifft, da hatte ich, was die Internationalisierung betrifft, widersprüchliches im Web gefunden. Entweder kann man da alle Texte übersetzen der vielleicht auch nicht. das ist mir noch nicht so ganz klar geworden. "Click" hatte ich vorhin zum ersten Mal entdeckt. Da scheint in der Doku auch nicht relevantes in Sachen Übersetzung der click-eigenen Texte dokumentiert zu sein.
Benutzeravatar
__blackjack__
User
Beiträge: 13122
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Ich mag `click` ganz gerne wenn es ausserhalb der Standardbibliothek sein darf. Wenn man eine Anwendung hat die nicht nur *einen* Satz an Optionen hat, sondern so etwas wie ”Unterkommandos”, nimmt einem das einiges an Arbeit ab. Und — jetzt natürlich nicht mehr wichtig — gleicht das auch ein paar Unterschiede zwischen Python 2 und 3 aus. Zum Beispiel um an Binärversionen der Standard-Ein- und Ausgabe(n) zu kommen.

Drauf gekommen bin ich mal über einen ”Trick” den ich öfter benutze: Regelmässig mal die *kompletten* Abhänhigkeiten von meinen Projekten anschauen. Denn wenn ich Bibliothek X verwende, und die Bibliothek Y verwendet, dann macht es ja Sinn sich Y mal anzuschauen ob da auch was drin ist, was ich direkt selbst gebrauchen kann, denn die Bibliothek ist ja sowieso schon da. Nix verkommen lassen. 🤓 `click` hat man beispielsweise bei Flask automatisch zur Verfügung.

Über I18N habe ich mir bei Kommandozeilenprogrammen noch nie Gedanken gemacht. Da kann ich also nichts zu sagen, in wie weit es da vielleicht irgendwelche generierten Texte gibt, an die man nicht heran kommt.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
nezzcarth
User
Beiträge: 1638
Registriert: Samstag 16. April 2011, 12:47

Ich verwende so gut wie ausschließlich das argparse-Modul aus der Standardbibliothek. Es beherrscht alles, was ich brauche und die Features sind ja doch relativ umfangreich. Ich habe gerne das komplette CLI-Handling übersichtlich an einer Stelle, in der Regel einer Funktion und das ist problemlos möglich.

Ein Spezialfall ist das 'fileinput'-Modul aus der Standardbibliothek, das ich manchmal, vor allem in kleinen Wegwerfskripten, gerne verwende. Es ist kein CLI-Parser in dem Sinne, deckt aber den häufigen Spezialfall, dass man Dateien, die eingelesen werden sollen, als Parameter angeben möchte, ab. Es lässt sich auch mit argparse kombinieren.

In fremdem Code sehe ich noch relativ oft das getopt-Modul aus der Standardbibliothek. Der "Clou" hieran ist, dass das ein verbreiteter (aber auch eher altmodischer) Mechanismus bzw. eine C-Funktion ist, den/die es für diverse Programmiersprachen gibt. Wenn man also den (mehr oder weniger) selben Mechanismus in Python wie in C oder Bash verwenden möchte, wäre das hiermit möglich. Ich würde es aber nicht verwenden, weil ich es sehr umständlich finde. Auch bei Portierungen nach Python ist es m.M.n. besser, das CLI-Interface gleich auf argparse anzupassen.

'click' scheint sehr beliebt zu sein, aber leider werde ich damit nicht warm. Ich habe das Gefühl, die Bibliothek möchte die Struktur meines Scripts zu sehr mitbestimmen und das CLI-Handling ist irgendwie über den gesamten Code verstreut. Vielleicht habe ich es auch nicht richtig verstanden oder so. Außerdem finde ich es oft nicht so gut, für so etwas Grundlegendes wie CLI-Parsing eine externe Bibliothek zu verwenden. Aber das ist ja immer eine Abwägung im Einzelfall.

Ansonsten finde ich Bibliotheken interessant, die das CLI-Parsing sozusagen über das Auswerten der Doku des CLI-Interfaces erzeugen. Bibliotheken mit diesem Ansatz habe ich vor allem in Perl häufiger verwendet. In Python ist docopt glaube ich die beliebteste Umsetzung dieses Konzepts.
Benutzeravatar
snafu
User
Beiträge: 6744
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ansonsten gäbe es noch Fire (https://github.com/google/python-fire).

Das ist ähnlich wie click, aber im Detail anders aufgebaut.
Benutzeravatar
__blackjack__
User
Beiträge: 13122
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@nezzcarth: Das man mit `click` das ein bisschen mehr verteilen kann ist einer der Vorteile. Ich verstehe das total, dass man die Kommandozeilenverarbeitung an *einer* Stelle haben möchte. Bei einfachen Programmen verwende ich deshalb auch `argparse`. Die Sachen wo ich `click` verwende sind dann schon so gross/umfangreich, dass eine einzelne Funktion, in die man die Kommandozeilenverarbeitung steckt, schon viel zu gross wäre. Da habe ich dann mindestens ein Modul `cli` oder in der `__main__.py` mehrere mit `click` dekorierte Funktionen. Und dann gibt es noch die Fälle wo es noch grösser wird. Beispielsweise eine Webanwendung mit mehreren Aufgabenbereichen die jeweils in Packages aufgeteilt sind, wo dann auch die ”housekeeping”-Geschichten die man manuell aufruft (Benutzer verwalten, ab und zu was in der DB aufräumen, Abgleich von Daten aus externen Systemen, …) in den Packages stecken, wo sie thematisch hingehören.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
nezzcarth
User
Beiträge: 1638
Registriert: Samstag 16. April 2011, 12:47

@__blackjack__: Danke für die Erklärung. Insb. das Beispiel mit größeren Webanwendungen kann ich gut nachvollziehen. Für große Webanwendungen verwende ich Django und setze die Funktionalitäten, die du beschreibst als Management-Comamands um (was ein Wrapper um argparse ist). Es leuchtet aber ein, dass man das bei Webframeworks, die soetwas nicht mitbringen mit z.B. click umsetzt.
Benutzeravatar
__blackjack__
User
Beiträge: 13122
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@nezzcarth: Ich habe das bei einer Webanwendung mit `bottle`, aber abgeschaut von Flask — denn Flask selbst verwendet `click`. Dort kann man eigene Management-Kommandos so einbinden: https://flask.palletsprojects.com/en/2. ... m-commands

Die Webanwendung mit `bottle` sollte gar nicht *sooo* gross werden. Aber wie das so ist — es fing als *eine* PHP-Seite an, die Informationen aus der DB eines anderen Systems als HTML-Tabelle aufbereitet angezeigt hat, die der *eine* Anwender dann manuell über die Zwischenablage in eine Tabellenkalkulation eigefügt hat um damit Dinge zu tun, und keine 12 Jahre später ist das eine Mehrbenutzeranwendung, die zusätzlich auch eine eigene DB hat, und viele Dinge tut. Unter anderem auch fertige Tabellenkalkulationsdokumente ausspucken. Und Teile der Funktionalität des anderen Systems übernommen hat. Und selbst Dienste für andere Anwendungen im Gesamtsystem anbietet.

Für das ersetzen einer einzelnen PHP-Seite mit einer Tabelle erschien mir Django damals zu sehr mit Kanonen auf Spatzen geschossen. Zudem ist SQLAlchemy flexibler wenn es um bereits bestehende Datenbanken geht an denen man nichts ändern kann. Flask war damals noch Beta und war noch nicht so verbreitet wie heute. Wenn ich das mit heutigem Wissen der Entwicklung aufgesetzt hätte, dann eher mit Flask als mit Bottle.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
snafu
User
Beiträge: 6744
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Zumal sich bei Bottle in den letzten Jahren nicht mehr wirklich viel getan hat. Der letzte Commit auf Github ist von September 2022, aber auch schon davor war's relativ mau um die Weiterentwicklung bestellt. Wenn man das noch für neue Projekte nimmt, dann setzt man IMHO auf ein totes Pferd.

Schon schade, weil Bottle AFAIK das Routing via Dekoratoren als erstes in Python eingeführt hat und das ja schon ein cooles Konzept ist. Dann kam Flask und hat es auf lange Sicht irgendwie besser gemacht. Und eine Zusammenarbeit der beiden Projekte hatte Marcel ja damals abgelehnt, wenn ich das richtig im Kopf habe. Jedenfalls scheint da nicht mehr viel Lust und/oder Zeit für das Projekt seinerseits bestehen.
Benutzeravatar
__blackjack__
User
Beiträge: 13122
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@snafu Sehe ich nicht ganz so düster. Bottle ist halt im Grunde einfach fertig. Der Witz ist ja, dass da alles ”minimal” und in einer Datei steckt. Was soll sich denn da noch tun? Neue Features ja eher nicht. Das letzte Release auf PyPI ist von März diesen Jahres.

Was grösseres würde ich mittlerweile auch mit Flask machen, aber bei Bottle ist es halt sehr schön, dass man das einfach direkt zu einem anderen Modul mit ins Verzeichnis packen kann, und so supersimpel eine kleine ”Web”anwendung schreiben kann, ohne das wirklich etwas ”installiert” werden muss. Auch praktisch für kleine GUIs für Windows.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
DeaD_EyE
User
Beiträge: 1021
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Ich nutze fast ausschließlich argparse. Interessant finde ich typer: https://typer.tiangolo.com/
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Benutzeravatar
__blackjack__
User
Beiträge: 13122
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Typer setzt ja auf `click` auf.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

snafu hat geschrieben: Mittwoch 5. Juli 2023, 18:59 Und eine Zusammenarbeit der beiden Projekte hatte Marcel ja damals abgelehnt, wenn ich das richtig im Kopf habe.
Soweit ich mich erinnere, hatte Marcel seinerzeit gehofft, dass Armin zu bottle beitragen würde. Stattdessen hat dieser bereits bestehende Tools wie u.a. Werkzeug und Jinja zu Flask (letztendlich eine Namensvariante von bottle) kombiniert und mit einer ansprechenden Dokumentation versehen. Letzteres war aus meiner Sicht die eigentliche Arbeit und vermutlich der Hauptgrund zur mittlerweile weiten Verbreitung von Flask.
Benutzeravatar
__blackjack__
User
Beiträge: 13122
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@kbr: Denke nicht dass das der Hauptgrund ist. Der dürfte eher sein, dass die meisten die Bottle verwenden, letztlich wenn das Projekt wächst, sich nach zusätzlichen Komponenten umschauen, und dann früher oder später Jinja, Werkzeug, und SQLAlchemy mit an Bord haben, und anfangen sich so etwas wie Flask nach zu bauen. Und wenn man das mal gemacht oder gesehen hat, wird das nächste Projekt dann gleich mit Flask aufgesetzt.

Wie hätte denn so eine Zusammenarbeit denn aussehen sollen? *Der* Punkt von Bottle ist ja das *eine* „self contained“ Modul, das alles enthält. Deswegen ist das IMHO auch immer noch eine sinnvolle Alternative zu Flask, für Fälle wo das ein Vorteil darstellt.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

@__blackjack__: Ich vermute dennoch, dass die ausführliche und leicht zugängliche Dokumentation von Flask entscheidend für die Verbreitung war. Wäre es das Konzept alleine gewesen, hätte Pyramid das Rennen machen müssen, das mit Zope-Wurzeln früher unter repoze.bfg bzw. pylons segelte, aber sowohl vom Namen als auch der Dokumentation recht sperrig war – was Flask kann, konnte Pyramid schon lange.

Bei der "Zusammenarbeit" gehe ich davon aus, dass Marcel ursprünglich annahm, Armin könnte bei der Entwicklung von bottle hinzustoßen. Statt dessen aber hat dieser die Idee des Microframework aufgegriffen, Flask aus der Taufe gehoben und gegen bottle positioniert.
Benutzeravatar
__blackjack__
User
Beiträge: 13122
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@kbr: Ich finde die Dokumentation von Bottle jetzt nicht schwer zugänglich. Ich denke eher das es ”Marketing” war was zu einer Community geführt hat, die letztendlich einen wirklich grossen Pluspunkt darstellt. Flask startete ja als Aprilscherz bei dem Armin, soweit ich das verstehe, selber überrascht war wie viel positive Aufmerksamkeit das gebracht hat. So ganz ohne Dokumentation, mit leeren Versprechen was das angeblich können soll, und einfach schnell mal Werkzeug und Jinja in *eine* Datei + ein bisschen „glue code“, eine schicke Webseite und ein Github-Repo. Mehr war das ja nicht, und mehr sollte das ursprünglich ja auch nicht werden. Das war also deutlich weniger als die ganzen Konkurrenten boten. Und trotzdem gab es so viel Rückmeldung, dass ein Jahr später Flask ein beliebtes *echtes* Webrahmenwerk war, mit gut frequentierter Mailingliste und ein beliebtes Projekt auf Github.

Bezüglich der Zusammenarbeit verstehe ich halt immer noch nicht wie das hätte funktionieren sollen. Der Ursprung von Flask, der Aprilscherz, basierte ja schon auf Werkzeug und Jinja. Und hatte zum Ziel sich über „eine Datei Micro-Webrahmenwerke“ lustig zu machen. Da ist ja die Basis für eine Zusammenarbeit ja schon recht klein.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
DeaD_EyE
User
Beiträge: 1021
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

__blackjack__ hat geschrieben: Donnerstag 6. Juli 2023, 13:31 Typer setzt ja auf `click` auf.
Mag sein. Die Besonderheit von typer ist die Nutzung der Annotationen.
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

@__blackjack__: Das "Marketing" war die Dokumentation, die ansprechend gestaltet war (sowie die Wahl von Github statt bitbucket). Das war die Hauptarbeit, der Rest war im wesentlichen tatsächlich "glue". Der anschließende Erfolg mag Armin überrascht haben, zeigt aber, dass die ursprüngliche Idee hinter Bottle gut war, und Flask von vielen wohl nicht als Aprilscherz aufgenommen wurde – und die Bekanntheit von Armin mag auch dazu beigetragen haben. Der von Marcel (möglicherweise unterstellten) erhofften "Zusammenarbeit" an Bottle war mit der Publikation von Flask natürlich sofort eine Absage erteilt.
Benutzeravatar
__blackjack__
User
Beiträge: 13122
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@kbr: Die Dokumentation von dem Aprilscherz gab es nicht, da war nur das versprechen einer tollen Dokumentation. Flask war nicht der Aprilscherz, der hiess Denied. Und der Marketing-Erfolg von diesem Aprilscherz, der nur aus netten Versprechen und was schnell zusammengeklöppelten bestand, ist IMHO wichtig gewesen für den Erfolg von Flask. Denied war nicht ernst gemeint, und im Grunde hätte das auch jeder gesehen, der mal den Text auf der Webseite mit der Implementierung verglichen hätte. Erst die überraschend positive und zahlreiche Rückmeldung zu dem Scherz hat zu Flask geführt. Der Erfolg war halt schon *vor* dem tatsächlichen Rahmenwerk da, und auch bevor da Dokumentation war. Das war aus meiner Sicht die Initialzündung für eine Community, die IMHO wichtiger war/ist, und deren Rückmeldung dann ja auch in die gute Dokumentation geflossen sind. Was natürlich auch wieder für neue Benutzer sorgt. Wobei ich die Dokumentation von Bottle wie gesagt nicht schlecht finde. Klar ist das weniger, aber Bottle ist auch einfacher und hat (absichtlich) nicht so viele Features. Und Marketing ist ja auch die Origin-Story von Flask, weil die ja irgendwie witzig ist. Die Leute sind auf die scherzhaft gemeinte Vaporware reingefallen, dann lasst uns ihnen doch so etwas in echt und gut geben. Und dann ist da ein erfolgreiches Projekt draus geworden.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

@__blackjack__: Ich erinnere mich dunkel an Denied (das wäre mir ungestützt wohl nicht mehr eingefallen), und das dies als Scherz zumindest erkennbar hätte sein können. An die Doku erinnere ich mich erst mit Flask (kein Wunder, wenn Denied mit nichts daher kam). Und die Namenswahl Flask ist klar eine Anspielung an Bottle – das ist womöglich nicht bei allen gut angekommen. Mittlerweile weiß und interessiert das vermutlich kaum einen mehr.
Antworten