Hoofdstuk 8
Programma’s die argumenten accepteren
De interface van een programma is een contract
Hoofdstuk 7 eindigde met een echte converter, maar alleen voor de twee bestandsnamen die in main() stonden. Iemand kan geen andere invoer of uitvoer kiezen zonder het programma te bewerken. Dit hoofdstuk maakt van die vaste uitvoering een opdrachtregelinterface.
De shell zelf is niet opnieuw het onderwerp. Je weet al hoe je in een projecthoofdmap gaat staan en een Python-bestand uitvoert. Het nieuwe werk is bepalen wat het programma accepteert en wat elke mogelijke uitvoering terug belooft.
Schrijf de opdracht vóór de parser
Dit is de volledige interface die we bouwen:
python catalog.py INPUT_PATH OUTPUT_PATH [--minimum-quantity COUNT]
INPUT_PATH en OUTPUT_PATH zijn verplichte positionele argumenten. Hun betekenis volgt uit hun positie: eerst invoer, daarna uitvoer.
--minimum-quantity is een optie. De naam maakt de betekenis van de waarde zichtbaar; laat je de optie weg, dan wordt 0 gebruikt. Een aantal moet een geheel getal van nul of meer zijn. Het programma behoudt items waarvan de hoeveelheid minstens dat aantal is, zonder de volgorde te veranderen of duplicaten te verwijderen.
-h en --help tonen de interface zonder een conversie uit te voeren.
Twee uitvoerstromen en drie statussen
Een opdrachtregelprogramma heeft twee tekststromen. Gewone resultaten gaan naar stdout. Bruikbare foutmeldingen gaan naar stderr. Door ze te scheiden kan een ander hulpmiddel het geslaagde resultaat opslaan zonder er fouttekst doorheen te mengen.
Het programma eindigt ook met een exitstatus:
| Situatie | stdout | stderr | Status |
|---|---|---|---|
| Conversie slaagt | Wrote N items to PATH. | leeg | 0 |
| Invoer of catalogusgegevens zijn ongeldig | leeg | Could not convert catalog: ... | 1 |
| Argumenten ontbreken, zijn onbekend of ongeldig | leeg | gebruiksuitleg en parserfout | 2 |
| Hulp gevraagd | hulptekst | leeg | 0 |
Het uitvoerbestand is even precies afgesproken. Een geslaagde uitvoering schrijft gevalideerde UTF-8-JSON naar het gevraagde uitvoerpad. Een argumentfout start nooit een conversie. Een onverwachte programmeerfout krijgt nog steeds een traceback; die mag niet worden vermomd als beschadigde invoer.
Hoe weet het programma bij de opdracht python catalog.py source.csv result.json welk pad de invoer is?
Waarom hoort een verwachte melding over een onjuiste catalogus op stderr?
Hierna zet argparse de eerste twee onderdelen van dat geschreven contract om in waarden, zonder dat de converter CSV of JSON opnieuw hoeft uit te zoeken.
Probeer voordat je parsercode schrijft je interface in één zin aan Monty te beschrijven en vraag wat een gebruiker verrassend zou vinden. Interfaces zijn nu veel goedkoper te veranderen dan nadat ze bestaan.