0%

Een programma over bestanden verdelen · oefening

Importeer klassen duidelijk

models.py bevat kopieën van Question, Quiz en Attempt. main.py definieert nog steeds de originelen. Maak de verplaatsing af door die dubbele definities te vervangen door imports.

Het verbinden kost één regel en de keuze van die regel is een kleine ontwerpbeslissing die je honderden keren zult nemen.

Twee manieren om een naam te bereiken

Try it

Met die klasse in een module genaamd models kan dezelfde code die op twee manieren bereiken:

import models

question = models.Question("Which keyword starts a function?", "def", 2)
from models import Question

question = Question("Which keyword starts a function?", "def", 2)

import models haalt de module binnen en laat de namen achter de modulenaam staan. from models import Question haalt die ene naam rechtstreeks naar het huidige bestand.

main.py importeert namen uit models.py en report.py en houdt de naamruimten van de modules duidelijk.

Beide zijn gebruikelijk en correct. Ze verschillen in wat een lezer op de gebruiksplek ziet. In het diagram betekent ‘its own namespace’ de eigen naamruimte van de module; de bestandsnamen, klassenamen en aanroepen blijven Pythoncode.

Kiezen tussen de twee

models.Question(...) zegt elke keer waar de klasse vandaan komt. Dat is waardevol als een naam op zichzelf dubbelzinnig is en daarom schrijft niemand from datetime import *.

Question(...) leest beter wanneer de naam duidelijk is en vaak wordt gebruikt. Tien aanroepen van models.Question achter elkaar zijn ruis; bij de tweede vertelt de modulenaam je al niets meer wat je niet wist.

De gewoonte om aan te leren:

SituatieGeef de voorkeur aan
Een paar goed benoemde klassen die je voortdurend gebruiktfrom models import Question, Quiz
Een naam die op zichzelf weinig zegt (load, run, parse)import loader, daarna loader.load(...)
Twee modules die dezelfde naam beschikbaar makenBeide met import importeren en het voorvoegsel ze laten onderscheiden

Voor dit project is from models import Attempt, Question, Quiz de betere regel. Alle drie de namen zijn specifiek en main.py gebruikt ze herhaaldelijk.

report.py en models.py definiëren allebei een functie describe. Wat moet het bestand dat beide gebruikt doen?

Waar Python zoekt

from models import Question laat Python zoeken naar models.py, en de eerste plek waar het kijkt is de map van het programma dat wordt uitgevoerd. Daarom werkt het importeren van een bestand naast main.py gewoon, zonder configuratie.

Daarom is ook het bestand waarmee het programma start belangrijk, wat les 5 behandelt.

Eén gevolg dat nu al nuttig is om te kennen: een eigen bestand met de naam random.py of json.py zou eerder worden gevonden dan dat van de standaardbibliotheek. Elke import van die naam in het hele programma zou dan jouw bestand krijgen. De fout die daarop volgt is erg verwarrend. De oplossing is je module niet te vernoemen naar iets in de standaardbibliotheek.

De oefening

main.py krijgt de importregel en het is de moeite waard te beseffen wat er daarna gebeurt: het programma behoudt het gedrag, gebruikt de gedeelde definities in models.py en zegt nu bovenaan precies waarvan het afhangt.

Opdracht

Herstel main.py, het bestand dat bij de editor van deze les hoort.

Importeer Attempt, Question en Quiz uit models bovenaan het bestand en verwijder de drie klassedefinities die daar in de vorige les naartoe zijn verplaatst. Al het andere blijft: report_lines, build_quiz, main en de uitvoercontrole onderaan.

Gebruik from models import Attempt, Question, Quiz. Alle drie de namen zijn specifiek en worden hier herhaaldelijk gebruikt, wat past bij deze stijl.

Voer het programma uit. Het moet precies hetzelfde afdrukken als vóór de splitsing. Dat is het punt: de structuur veranderde en het gedrag niet.