← Python/Eigen typen
Les 2 van 8
MODULE 07 · 02◷ 26 min

Beginwaarden bij iedere nieuwe instantie

Na deze les kun je
  • __init__ gebruiken om objectattributen meteen in te stellen.
  • Standaardargumenten onderscheiden van expliciet opgegeven waarden.
  • Eigen nieuwe lijsten en buitenste lijstkopieën bewust maken.

Na ieder nieuw kaartje apart alle attributen invullen wordt snel herhaalwerk. Je kunt bovendien vergeten een noodzakelijke waarde te zetten. Een klasse kan haar eigen beginwaarden instellen, zodat een nieuw object meteen bruikbaar is.

Beginwaarden bij het maken

De initialisatiemethode __init__ wordt aangeroepen nadat een nieuwe instantie is aangemaakt. De argumenten uit bijvoorbeeld Ticket("Delft", 12) worden aan die methode doorgegeven. Zo kan de klasse zelf de bestemming en prijs op de instantie bewaren.

De eerste parameter heet volgens afspraak self en verwijst naar de nieuwe instantie. Python geeft die verwijzing bij deze aanroep zelf mee. De overige parameters schrijf je zoals bij de functies die je al kent.

Een toekenning aan self.destination bewaart de waarde bij het object. Alleen destination = destination verandert geen objectattribuut: dat werkt met de lokale parameternaam. De punt verbindt de waarde met de juiste instantie.

Beginwaarden via de initialisatiemethode
class Ticket:
    def __init__(self, destination, price):
        self.destination = destination
        self.price = price

first = Ticket("Delft", 12)
second = Ticket("Leiden", 8)
print(first.destination, first.price)
print(second.destination, second.price)
Verwachte uitvoer
Delft 12
Leiden 8

Iedere aanroep krijgt eigen toestand

__init__ wordt voor ieder nieuw exemplaar uitgevoerd. Daardoor kunnen twee reisbiljetten verschillende bestemmingen en prijzen krijgen. De waarden zijn na het maken gewoon via de attributen te lezen.

Ook standaardargumenten werken hier zoals bij gewone functies. Counter() kan bijvoorbeeld met nul beginnen, terwijl Counter(5) een andere beginwaarde krijgt. Een expliciete nul moet daarbij nul blijven; gebruik geen waarheidstest om een opgegeven waarde te vervangen.

__init__ geeft normaal None terug. Het object dat je van Ticket(...) krijgt, komt niet uit een return self in deze methode. Een andere retourwaarde uit __init__ wordt door Python afgewezen, dus laat de methode na haar toekenningen gewoon eindigen.

Let op veranderlijke beginwaarden

Een notitieboek heeft een lijst met notities nodig. Als je notes = [] rechtstreeks in het klasseblok zet, staat er één lijst bij de klasse. De twee instanties uit het voorbeeld zien daardoor dezelfde lijst zolang zij geen eigen attribuut hebben.

Een klasselijst wordt door twee instanties gezien
class Notes:
    notes = []

first = Notes()
second = Notes()
first.notes.append("Idee")
print(first.notes)
print(second.notes)
print(first.notes is second.notes)
Verwachte uitvoer
['Idee']
['Idee']
True

De gewenste afspraak is meestal dat ieder notitieboek met een eigen lege lijst begint. Maak die lijst dan binnen __init__ en bewaar haar op self.notes. De expressie [] wordt op die plek bij iedere initialisatie opnieuw uitgevoerd.

Plaats van de lijstGevolg voor twee nieuwe objecten
Eén lijst in het klasseblokKan als gedeelde beginwaarde zichtbaar zijn
Nieuwe lijst in iedere initIedere instantie krijgt haar eigen lijst

Veelgemaakte fout: de invoerlijst blijven delen

Een constructor kan ook een bestaande lijst ontvangen. Met self.items = items bewaar je dezelfde lijst als de aanroeper. Een latere wijziging aan die invoerlijst wordt dan zichtbaar in je nieuwe object.

Wanneer het contract een eigen lijst vraagt, maak je een kopie met list(items). Dat is een kopie van de buitenste lijst, zoals in de collectiemodule. Veranderlijke objecten binnen die lijst worden daarmee niet automatisch diep gekopieerd.

Dit verschil is een eigendomsafspraak. Soms wil je bewust dezelfde lijst delen, maar de Queue uit deze oefening bewaart een eigen kopie van de ontvangen platte lijst. De oorspronkelijke volgorde en herhalingen blijven behouden.

Jouw vier beginpatronen

Je werkt met eenvoudige klassen die alleen gegevens instellen. Book bewaart titel en aantal pagina's, Counter gebruikt een standaardwaarde en Notebook begint met een nieuwe notitielijst. Queue neemt bestaande invoer over in een eigen lijst.

Deze les voegt nog geen domeinvalidatie toe. Lege titels, nul en negatieve tellerstanden blijven geldig wanneer de opdracht dat niet beperkt. De controles onderscheiden bewaren, kopiëren en onbedoeld delen aan de hand van de echte objecten.

AAN DE SLAG 0/4
1

Een boek meteen instellen

Maak Book met __init__(title, pages) die de ontvangen waarden op title en pages van de instantie bewaart. Bewaar lege tekst, spaties, nul en negatieve waarden precies; deze les voegt geen validatie toe.

2

Een standaardbeginstand

Maak Counter met __init__(start=0) die de beginstand op value bewaart. Zonder argument begint zij op nul; een expliciet ontvangen getal, ook nul of negatief, blijft onveranderd.

3

Iedere instantie een eigen lijst

Maak Notebook met __init__(title) die title precies bewaart en notes op een eigen nieuwe lege lijst zet. Een wijziging aan één notitieboek mag andere of latere instanties niet raken.

4

Een bestaande lijst bewust kopiëren

Maak Queue met __init__(items) die een eigen buitenste lijstkopie op items bewaart. Behoud volgorde en herhalingen. Latere wijzigingen aan de ontvangen lijst of aan een andere Queue mogen deze lijst niet veranderen.

Onthoud dit

  • __init__ stelt een nieuwe instantie in via self.
  • Standaardargumenten veranderen de normale betekenis van expliciete nulwaarden niet.
  • Kies bewust tussen een eigen nieuwe lijst, een kopie en een gedeelde verwijzing.

Hierna voeg je methoden toe die de toestand van een bestaand object gebruiken of veranderen.

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.