mitmario.dev

Argumente von der Kommandozeile

Python Sandbox 3 Min Lesezeit 4 BeispieleLektion 6 von 7

Du brauchst jede Woche dieselbe Fahrtkostenrechnung, nur mit anderen Kilometern. Dafür jedes Mal die Datei zu ändern, nervt. Bisher gab es drei Wege, auf denen ein Programm seine Werte bekommt, fest im Code, über input() und aus einer Datei.

Ein Werkzeug, das man im Terminal startet, bekommt sie oft auf einem vierten Weg, gleich beim Start. Etwa mit python fahrt.py 137. Alles hinter dem Dateinamen sind Argumente der Kommandozeile (command line arguments).

Was in sys.argv steht

Was in sys.argv steht
import sys

print(sys.argv)

Die Argumente stehen im Modul sys (system) in einer Liste namens argv (argument vector, die Liste der Argumente). Startest du mit python fahrt.py 137, steht darin ['fahrt.py', '137']. An Position 0 steht der Name der Datei selbst, und die Werte fangen erst bei Position 1 an. Das vergisst man gern. Dann wird mit dem Namen des Programms gerechnet.

Getrennt wird an den Leerzeichen, so wie im Terminal getippt. Ein Wert, der selbst ein Leerzeichen enthält, kommt in Anführungszeichen. python gruss.py "Mia Müller" ist ein einziger Wert.

Vorn in der Befehlsleiste steht der Befehl, mit dem das Beispiel startet, samt seinem Wert. Andere Werte kannst du im Terminal selbst tippen. Mit dem zweiten Befehl der Leiste stehen zwei Werte in der Liste.

Text, wie bei input()

Kilometer beim Start
import sys

kilometer = float(sys.argv[1])
print(f"Fahrtkosten: {kilometer * 0.30:.2f} Euro")

Fahrtkosten, 30 Cent je Kilometer. Alles in sys.argv ist Text, auch wenn es wie eine Zahl aussieht, genau wie bei input(). Deshalb steht float() davor, und erst dann wird gerechnet. 137 Kilometer kosten 41,10 Euro. Mit dem Befehl aus der Befehlsleiste rechnet dasselbe Programm für 250 Kilometer, und keine Zeile im Code ändert sich.

Wenn ein Wert fehlt

Ohne Kilometer gestartet
import sys

kilometer = float(sys.argv[1])
print(f"Fahrtkosten: {kilometer * 0.30:.2f} Euro")

Dasselbe Programm, nur ohne Wert gestartet. In sys.argv steht dann nur ['fahrt.py']. sys.argv[1] gibt es nicht, also kommt IndexError: list index out of range.

Wenn du das Programm selbst geschrieben hast, weißt du damit, was passiert ist. Wer es nur benutzt, sieht einen Traceback und ist danach so schlau wie vorher. Was er hätte tippen sollen, steht da nämlich nicht.

Eine Aufrufzeile statt eines Tracebacks

Eine Aufrufzeile statt eines Tracebacks
import sys

if len(sys.argv) != 2:
    sys.exit("Aufruf: python fahrt.py KILOMETER")

kilometer = float(sys.argv[1])
print(f"Fahrtkosten: {kilometer * 0.30:.2f} Euro")

Ein Werkzeug prüft deshalb zuerst, ob die Zahl der Werte stimmt. len(sys.argv) != 2 heißt, es sind nicht genau der Dateiname und ein Wert. In dem Fall kommt sys.exit("…") dran. Der Text sagt, wie der Aufruf richtig aussieht, und das Programm ist sofort zu Ende. Was dahinter steht, läuft nicht mehr.

sys.exit mit einem Text erledigt zwei Dinge auf einmal. Der Text landet auf dem Fehlerkanal, wo Meldungen hingehören. Und das Programm endet mit dem Exit-Code 1, also mit „hat nicht geklappt“ aus Lektion 1.4. Der Befehl aus der Befehlsleiste endet auf echo $?, und damit siehst du beides im Terminal, die Zeile in Rot und darunter die 1. Wenn ein anderes Programm deins startet, etwa eine Aufgabenplanung, erkennt es an dieser Zahl, ob alles geklappt hat.

Die Zeile selbst folgt einer alten Abmachung. Auf Englisch fängt sie mit usage: an, hier mit „Aufruf:“, und was man einsetzen soll, steht in Großbuchstaben. Wenn du so eine Zeile siehst, weißt du ohne Anleitung, was zu tippen ist.

Für Werkzeuge mit vielen Werten und Schaltern gibt es das Modul argparse. Es baut die Aufrufzeile selbst, prüft die Werte und zeigt eine Hilfe, wenn man --help tippt. Bei ein oder zwei Werten ist das mehr, als man braucht, und sys.argv liest sich leichter. Einen Schalter bekommt der Aufräumer im nächsten Abschnitt, und solange --wirklich fehlt, zeigt er nur, was er tun würde.

Auf deinem eigenen Rechner tippst du denselben Befehl in ein Terminal. Wie Python dorthin kommt, steht ganz am Anfang des nächsten Abschnitts.

Was die Aufgabe will

Ein Bruttorechner für die Kommandozeile soll den Nettobetrag und den Steuersatz beim Start bekommen, python main.py 100 7, und den Bruttobetrag ausgeben. Wenn nicht genau so viele Werte kommen, soll er sagen, wie der Aufruf aussieht, und mit dem Exit-Code 1 enden.

Zum Mitnehmen

Alles, was beim Start hinter dem Dateinamen steht, landet in sys.argv, einer Liste aus Texten. Der erste Eintrag ist der Dateiname, die Werte folgen dahinter. Fehlt einer, schreibt sys.exit("Aufruf: …") auf den Fehlerkanal, wie der Aufruf richtig aussieht, und das Programm endet mit dem Exit-Code 1.

Jetzt du

Basis Konto, kostenlos

Zu dieser Lektion gehört eine Aufgabe. Du schreibst den Code selbst, und nach jedem Lauf sagt dir eine Prüfliste, was schon stimmt.

Dafür brauchst du das Basis Konto. Es kostet nichts, und ein Passwort gibt es auch nicht.

In diesem Kurs läuft dein Code auf einem Server. Dafür hat das Basis Konto 1 Stunde im Monat, mehr Zeit gibt es mit dem Premium Konto.

Was in dieser Lektion steckt

  • Artikel mit 4 Beispielen zum Ausprobieren

    Steht hier, ohne Konto lesbar.

  • Aufgabe, dein Code läuft auf einem Server

    Öffnet sich mit dem Basis Konto.