Sprint 7 ยท Methodes & self  ยท  US1: State via een eigen methode

Als gamedeveloper, wil ik dat elk spelobject zijn eigen toestand binnen zichzelf bijhoudt en aanpast, zodat een losse functie nooit per ongeluk het verkeerde object of een zwevende variabele raakt.

Taak 1: De state die buiten bereik valt

Je hebt een Player-object met een attribuut score. Maar een externe functie weet niets van dat object โ€” die past per ongeluk een zwevende variabele aan. Je leert zien waarom state-wijzigingen binnen het object moeten plaatsvinden.

Een externe functie raakt het verkeerde ding

Stel je hebt in sprint 6 een Lamp-class gemaakt met een attribuut self.is_on. Nu wil je een functie schrijven die een lamp aanzet. Zonder methode ziet dat er zo uit:

is_on = False          # losse globale variabele

class Lamp:
    def __init__(self, name):
        self.name = name
        self.is_on = False  # elk object heeft zijn eigen is_on

lamp1 = Lamp("living room")
lamp2 = Lamp("bedroom")

def turn_on():          # losse functie
    global is_on
    is_on = True       # OEPS: dit is de globale variabele, niet lamp1.is_on!

turn_on()
print(lamp1.is_on)     # False โ€” lamp1 is NIET aangezet!
print(is_on)           # True  โ€” maar dit is de losse globale, niet van lamp1

De functie past is_on aan โ€” maar dรกt is de globale variabele, niet het attribuut van lamp1. Lamp1 weet hier niets van.

Twee dingen met dezelfde naam. is_on (globaal) en lamp1.is_on zijn twee compleet aparte dingen. Python zoekt ze op in een andere ruimte. De functie past de globale aan. lamp1.is_on staat nog gewoon op False.

Zie het mislopen

Druk op Schakel (externe functie). De globale variabele verandert โ€” maar de lampen blijven uit. Druk daarna op Reset.

Globale variabele  is_on = False
๐Ÿ’ก
lamp1
is_on = False
๐Ÿ’ก
lamp2
is_on = False
De fix (volgende taak): Verplaats turn_on() naar binnen de class, als een methode. Dan schrijf je lamp1.turn_on() en Python weet precies welk object bedoeld wordt โ€” altijd de juiste lamp.
>>> Oefenomgeving: Python REPL Simulator

Voel het verschiil tussen de globale variabele en het object-attribuut.

  1. lamp1 = Lamp("living room")
  2. lamp2 = Lamp("bedroom")
  3. turn_on() โ€” roep de losse functie aan.
  4. is_on โ€” bekijk de globale variabele. Wat zie je?
  5. lamp1.is_on โ€” bekijk het attribuut van lamp1. Verschil?
  6. lamp2.is_on โ€” en lamp2?
Python 3.11 REPL Simulator ยท typ een commando en druk op Enter. # Beschikbare objecten: # Lamp("name") โ€” class met self.is_on = False # turn_on() โ€” losse functie die de globale is_on aanpast
>>> 
๐Ÿงฉ

Jouw opdracht: voel de globale-vs-object bug

Je bouwt een mini-versie van je speler met รฉรฉn attribuut en รฉรฉn losse functie โ€” zodat je de bug met eigen ogen kunt zien: een losse functie met global verandert een zwevende variabele, niet je object.

  1. Maak een globale variabele score = 0.
  2. Maak een class Player met in __init__ onder andere self.score = 0.
  3. Schrijf een losse functie increase_score() die met global de globale score met 10 verhoogt.
  4. Maak twee spelers: p1 en p2.
  5. Roep increase_score() aan en print daarna score, p1.score en p2.score.
  6. Schrijf in commentaar op: wat klopt er niet en waarom?

Acceptatiecriteria

  • De code bevat een globale score en een class Player met een eigen self.score.
  • Na increase_score() is de globale score gelijk aan 10.
  • Na increase_score() zijn p1.score en p2.score beide nog 0.
  • In commentaar staat uitgelegd waarom de losse functie het verkeerde ding raakt.