Benoemde velden laten instellen
Maak Reading als echte dataclass met velden label: str en value: int, in die volgorde. Gebruik de gegenereerde initialisatie en bewaar ontvangen waarden precies, ook lege tekst, spaties, nul en negatieven.
Veel gegevensklassen herhalen dezelfde code: argumenten ontvangen, attributen vullen en een leesbare weergave maken. Wanneer de klasse vooral een verzameling velden beschrijft, kan Python een deel van dat werk overnemen. Je blijft zelf verantwoordelijk voor de betekenis en het gedrag van die gegevens.
Een dataclass is een klasse waaraan de decorator @dataclass gewone terugkerende methoden toevoegt. Je importeert de decorator uit dataclasses. Daarna zet je de notatie boven het klasseblok.
Een veld krijgt een naam en een typeannotatie, bijvoorbeeld name: str of count: int. De dubbele punt beschrijft hier het bedoelde soort waarde. Python gebruikt deze aanwijzing niet als automatische controle bij het aanroepen van de constructor.
Voor deze les hoef je de volledige wereld van typeannotaties nog niet te kennen. Je gebruikt str voor tekst, int voor gehele getallen en list[str] voor een lijst die volgens de afspraak teksten bevat. De volgende module gaat dieper in op zulke aanwijzingen en het controleren van typen.
Een gewone dataclass maakt standaard een __init__ voor haar velden en een leesbare repr. Ook krijgt zij een vergelijking van haar veldwaarden. Voer het voorbeeld uit en let op de veldnamen in de weergave.
from dataclasses import dataclass
@dataclass
class GameSettings:
name: str
lives: int = 3
first = GameSettings("Rustig")
second = GameSettings("Oefenen", lives=0)
print(first)
print(second.lives)
print(first == GameSettings("Rustig"))GameSettings(name='Rustig', lives=3) 0 True
Je ziet daardoor de opgeslagen gegevens in plaats van alleen een ondoorzichtig objectadres. Een veld met = 3 krijgt die standaardwaarde wanneer de aanroeper niets opgeeft. Een expliciet opgegeven nul of False blijft een echte opgegeven waarde.
De volgorde van de velden bepaalt hier de volgorde van de gewone constructorargumenten. Zet vereiste velden vóór velden met een standaardwaarde. Je kunt daarna ook de bekende keywordargumenten gebruiken om een waarde duidelijk te benoemen.
Bij een veranderlijke beginwaarde wil je opnieuw bepalen wie de gegevens bezit. default_factory beschrijft een functie die een standaardwaarde maakt wanneer dat argument ontbreekt. Met field(default_factory=list) laat je voor zo'n nieuwe instantie een lege lijst maken.
from dataclasses import dataclass, field
@dataclass
class TodoGroup:
name: str
tasks: list[str] = field(default_factory=list)
first = TodoGroup("Vandaag")
second = TodoGroup("Morgen")
first.tasks.append("Bellen")
print(first.tasks)
print(second.tasks)
print(first.tasks is second.tasks)['Bellen'] [] False
Geef list zonder ronde haakjes door: de dataclass moet die functie later kunnen aanroepen. Met list() zou je de functie nu al uitvoeren en een lijst doorgeven waar een fabriek hoort. Een gewone [] als dataclass-standaardveld wordt eveneens afgewezen.
Een expliciet meegegeven lijst volgt een andere route. De fabriek is dan niet nodig en de gewone gegenereerde initialisatie bewaart die ontvangen lijst. Een dataclass kopieert dus niet automatisch alle constructorargumenten.
points: int vertelt wat je bedoelt, maar weigert een meegegeven tekst niet vanzelf. Wanneer jouw domein een echte controle vraagt, moet die controle in gewone Python-code worden uitgevoerd. De property uit de vorige les is een voorbeeld van zo'n bewuste bewaker.
Ook het toevoegen van @dataclass geeft een methode geen zakelijke betekenis. Een methode om punten toe te voegen schrijf je zelf, net als bij een gewone klasse. De decorator neemt het herhaalwerk voor de gegevensvorm over.
De opdrachten gebruiken eenvoudige dataclasses met velden, een gewone standaardwaarde, een nieuwe standaardlijst en een eigen methode. De controles kijken naar de echte dataclass en haar waarden. Een gewone klasse met alleen vergelijkbaar geprinte tekst laat die structuur niet zien.
Bewaar ontvangen waarden zoals het contract vraagt. Voeg geen automatische conversie, afronding of extra domeingrens toe. Let vooral op de verschillende betekenis van een ontbrekende lijst en een bewust meegegeven lijst.
Maak Reading als echte dataclass met velden label: str en value: int, in die volgorde. Gebruik de gegenereerde initialisatie en bewaar ontvangen waarden precies, ook lege tekst, spaties, nul en negatieven.
Maak Options als dataclass met title: str en retries: int = 3. Laat een ontbrekend retries op 3 uitkomen en bewaar expliciete waarden precies, ook nul. Voeg geen conversie of runtime-typecontrole toe; annotaties controleren dit niet vanzelf.
Maak Journal als dataclass met title: str en notes: list[str] = field(default_factory=list). Zonder notes krijgt iedere instantie een eigen nieuwe lijst. Een expliciet ontvangen lijst wordt volgens de gegenereerde initialisatie juist als dezelfde lijst bewaard.
Maak Score als dataclass met name: str en points: int = 0. Voeg add(amount) toe die amount bij points van dezelfde instantie optelt en de nieuwe punten teruggeeft. Nul en negatieve bedragen volgen gewone optelling.
default_factory maakt een standaardwaarde wanneer het argument ontbreekt.Hierna bepaal je wanneer twee afzonderlijke objecten dezelfde waarde voorstellen.
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.