← Python/Eigen typen
Les 5 van 8
MODULE 07 · 05◷ 28 min

Dataclasses nemen gegevenswerk over

Na deze les kun je
  • Een echte dataclass met benoemde velden gebruiken.
  • Standaardwaarden onderscheiden van expliciete argumenten.
  • Voor veranderlijke standaardgegevens een nieuwe lijst laten maken.

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.

Velden beschrijven

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.

De terugkerende methoden laten maken

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.

Velden leveren een constructor en weergave op
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"))
Verwachte uitvoer
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.

Een nieuwe standaardlijst

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.

De fabriek maakt voor iedere instantie een lijst
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)
Verwachte uitvoer
['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.

Veelgemaakte fout: de annotatie als bewaker zien

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.

Jouw gegevensklassen

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.

AAN DE SLAG 0/4
1

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.

2

Een gewone standaardwaarde gebruiken

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.

3

Nieuwe standaardlijst en expliciete lijst onderscheiden

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.

4

Eigen gedrag aan een dataclass toevoegen

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.

Onthoud dit

  • Een dataclass beschrijft velden en kan terugkerende methoden genereren.
  • Typeannotaties zijn aanwijzingen en geen automatische invoervalidatie.
  • default_factory maakt een standaardwaarde wanneer het argument ontbreekt.

Hierna bepaal je wanneer twee afzonderlijke objecten dezelfde waarde voorstellen.

main.py
UitvoerPython
›
›_

Hier komt je resultaat.

Voer je code uit en ontdek
wat je hebt gemaakt.

0/4 stappen
EVEN MEEKIJKEN

Bekijk hoe het kan.

Je mag de oplossing bekijken. Deze poging telt dan niet mee als afgeronde les. Met Reset kun je daarna opnieuw zelf oefenen.