Herbruikbare tekst zonder uitvoer maken
Maak label(name, count) in shipping_cli.py. Geef de tekst '<count> x <name>' terug zonder zelf iets af te drukken. Behoud ook nul en negatieve gehele aantallen zoals ze zijn.
Een ander programma wil je verzendlabel gebruiken, maar krijgt bij de import meteen een vraag om invoer. Dat is onhandig: de ander vroeg alleen om een functie. Je maakt daarom verschil tussen een module laden en een programma bewust starten.
Python geeft een module de bijzondere naam __name__. Bij een gewone import van shipping_cli.py is die naam shipping_cli. Wanneer dat bestand als startprogramma wordt uitgevoerd, krijgt de bovenste codeomgeving de naam __main__.
Een startbewaking gebruikt dit verschil: if __name__ == "__main__":. De code binnen die voorwaarde draait bij het rechtstreeks starten van het bestand. Bij een gewone import slaat Python dat blok over.
import greeting
print('module geladen')
print(greeting.message('Noor'))def message(name):
return f'Welkom, {name}'
if __name__ == '__main__':
print('dit is het startprogramma')module geladen Welkom, Noor
Functiedefinities buiten het blok blijven bij het importeren beschikbaar. De bewaking verbergt de functies dus niet; ze voorkomt alleen dat de startaanroep op dat moment gebeurt. Plaats ook geen input() of losse print() buiten die bewaking wanneer de module zonder bijwerkingen importeerbaar moet zijn.
De naam main is een gewone functienaam, geen verplicht Pythonwoord. Het is wel een herkenbare afspraak voor het startpunt. Door het startwerk in zo'n functie te zetten, kun je het rechtstreeks aanroepen en later gemakkelijker testen.
De functie main(argv=None) in deze les ontvangt optioneel een lijst met argumenten. Een expliciete lijst zoals ["boek", "--count", "2"] maakt de invoer zichtbaar bij de aanroep. Bij None mag de argumentparser de argumenten gebruiken waarmee het programma is gestart.
Geef alleen de eigen argumenten door: in de expliciete lijst hoort geen programmanaam vooraan. sys.argv bevat zo'n naam wel op positie nul. De standaardargumentparser weet dat onderscheid en regelt het bij None zelf.
Een argumentparser zet losse argumentteksten om in benoemde waarden. Met argparse.ArgumentParser() uit de standaardbibliotheek geef je aan welke argumenten het programma verwacht. add_argument("name") definieert bijvoorbeeld een verplichte naam.
Een optie als --count krijgt met type=int een gehele waarde en met default=1 een standaardwaarde. Na parse_args(argv) kun je die waarden als attributen lezen. De functie parse_options geeft hier een tuple met naam en aantal terug, zodat de rest van het programma geen parserobject nodig heeft.
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('name')
parser.add_argument('--rounds', type=int, default=1)
args = parser.parse_args(['wandeling', '--rounds', '3'])
print(args.name)
print(args.rounds, type(args.rounds).__name__)wandeling 3 int
Wanneer de tekst bij --count geen geheel getal is, meldt argparse de gebruiksfout en beëindigt het de opdracht met SystemExit(2). Dat is iets anders dan een willekeurige standaardwaarde kiezen. De opdrachten laten dit bestaande parsergedrag doorlopen.
De helper label(name, count) bouwt tekst zonder die af te drukken. main gebruikt de helper, schrijft het label één keer en geeft daarna nul terug. Een andere module kan daardoor de labeltekst hergebruiken zonder console-uitvoer te krijgen.
De startbewaking gebruikt raise SystemExit(main()). Daardoor wordt de retourwaarde van main de exitstatus van het gestarte programma: nul staat voor geslaagde uitvoering. Een gewone functieaanroep van main beëindigt de interpreter niet; die levert simpelweg de waarde nul op.
Een losse main() onderaan het bestand wordt ook bij een import uitgevoerd. Alleen de functie definiëren voorkomt dat niet. Zet uitsluitend de startaanroep onder de bewaking en laat de herbruikbare functies erbuiten staan.
Maak label(name, count) in shipping_cli.py. Geef de tekst '<count> x <name>' terug zonder zelf iets af te drukken. Behoud ook nul en negatieve gehele aantallen zoals ze zijn.
Maak parse_options(argv=None). Gebruik argparse voor een verplichte positionele name en een optionele --count met type int en standaardwaarde 1. Geef (name, count) terug; laat de bestaande SystemExit(2) van argparse bij ongeldige of ontbrekende argumenten doorlopen.
Maak main(argv=None). Ontleed argv met parse_options, maak het resultaat met label en druk die tekst precies één keer met een afsluitende newline af. Geef daarna het gehele getal 0 terug zonder vanuit main zelf SystemExit te werpen.
Zet onderaan shipping_cli.py de bewaking if __name__ == '__main__': met daarin raise SystemExit(main()). Bij importeren blijven de functies beschikbaar en verschijnt geen uitvoer; bij rechtstreeks starten worden de echte startargumenten gebruikt en wordt nul de exitstatus.
__name__ onderscheidt een gewone import van de bovenste startomgeving.main kan expliciete argumenten ontvangen.SystemExit doorgeeft.Hierna groepeer je samenhangende modules in een pakket met een duidelijk openbaar toegangspunt.
Voer je code uit en ontdek
wat je hebt gemaakt.
Je hoeft het niet in één keer goed te doen. Na het uitvoeren zie je hier welke stappen al kloppen.