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 Positionsargumenteninput_pathundoutput_path. Setzeallow_abbrev=False, damit nicht deklarierte Optionsschreibweisen Fehler bleiben.Ändere
maininmain(argv=None)und lies die Argumente überbuild_parser()ein.Gib beide eingelesenen Pfade an
convert_catalogweiter.Behalte das eng begrenzte Katalogfehler-Tupel aus Kapitel 7 bei, Status
1bei diesen Fehlern und Status0bei Erfolg.Gib in der Erfolgszeile den tatsächlich angeforderten Ausgabepfad aus.
Behalte den exakten geschützten Aufruf raise SystemExit(main()) bei.