0%

Programme, die Argumente annehmen · Übung

Die beiden Pfade einlesen

Der Konverter weiß bereits, wie Katalogdaten gelesen, validiert und geschrieben werden. Ein Kommandozeilenparser soll diese Arbeit nicht wiederholen. Seine Aufgabe ist enger: Argumenttext in die Werte umwandeln, die main an den Konverter weitergibt.

argparse gehört zu Pythons Standardbibliothek. Du musst nichts installieren.

Einen Parser an einer Stelle aufbauen

Ergänze den Import und eine Funktion, deren einzige Aufgabe die Beschreibung der Schnittstelle ist:

import argparse


def build_parser():
    parser = argparse.ArgumentParser(
        description="Convert a catalog CSV file to validated JSON.",
        allow_abbrev=False,
    )
    parser.add_argument("input_path", help="CSV catalog to read")
    parser.add_argument("output_path", help="JSON catalog to write")
    return parser

Die Argumentnamen werden zu Attributen. Das Einlesen von ["source.csv", "result.json"] liefert einen Namensraum, dessen input_path den Wert "source.csv" und dessen output_path den Wert "result.json" hat. Es bleiben Strings, die die Dateifunktionen aus Kapitel 7 bereits akzeptieren.

ArgumentParser ergänzt außerdem -h und --help. Weil dieselben Festlegungen sowohl das Einlesen als auch die erzeugte Hilfe steuern, bleiben diese beiden Oberflächen bei Änderungen der Schnittstelle aufeinander abgestimmt.

allow_abbrev=False hält die Grammatik exakt. Der Anfang einer langen Option ist keine weitere geheime Schreibweise: Nicht deklarierte Optionsnamen bleiben Parserfehler.

Tests und Shell denselben Einstiegspunkt geben

Ändere den Funktionskopf in:

def main(argv=None):

Lies dann die beiden Werte ein und gib sie weiter:

args = build_parser().parse_args(argv)
document = convert_catalog(args.input_path, args.output_path)

Wenn argv den Wert None hat, liest argparse die Argumente, mit denen die Shell das Programm tatsächlich gestartet hat. Ein Aufrufer kann stattdessen eine Liste übergeben. Das ist keine Hintertür nur für Tests, sondern eine Schnittstelle mit zwei Möglichkeiten, ihre Eingabe zu erhalten. Genau dadurch kann Kapitel 10 diesen Befehl ganz ohne Shell prüfen.

Aktualisiere die Erfolgsmeldung so, dass sie args.output_path verwendet. Behalte die vorhandene eng begrenzte Behandlung von Katalogfehlern vorerst bei. Die nächsten Lektionen ergänzen die Option und senden den Fehlertext an den endgültigen Datenstrom.

Überzeuge dich selbst, dass die Pfade wirklich weitergegeben werden. Führe den Befehl mit zwei bisher unbenutzten Dateinamen aus und prüfe, ob die Ausgabe am gewünschten Ort landet, nicht in catalog.json. Führe ihn dann mit --help und mit einem fehlenden Pfad aus und lies, was argparse von selbst tut.

Warum nimmt main das Argument argv=None an, statt immer sys.argv zu lesen?

Aufgabe

Ergänze in catalog.py die argparse-Schnittstelle aus der Standardbibliothek.

  • Importiere argparse.

  • Definiere build_parser() mit der festgelegten Beschreibung und den erforderlichen Positionsargumenten input_path und output_path. Setze allow_abbrev=False, damit nicht deklarierte Optionsschreibweisen Fehler bleiben.

  • Ändere main in main(argv=None) und lies die Argumente über build_parser() ein.

  • Gib beide eingelesenen Pfade an convert_catalog weiter.

  • Behalte das eng begrenzte Katalogfehler-Tupel aus Kapitel 7 bei, Status 1 bei diesen Fehlern und Status 0 bei Erfolg.

  • Gib in der Erfolgszeile den tatsächlich angeforderten Ausgabepfad aus.

Behalte den exakten geschützten Aufruf raise SystemExit(main()) bei.