Sprint 7 Β· Methodes & self  Β·  US2: Methodes zijn geen functies

Als developer, wil ik gedrag vastleggen bij de data waar het bij hoort in plaats van in losse functies ernaast, zodat elke aanroep automatisch weet op welk object hij werkt.

Taak 1: Dezelfde actie, maar wie is het slachtoffer?

Een losse functie decrease_energy(dog, points) zweeft vrij rond in je code β€” je kunt hem per ongeluk aanroepen met elk willekeurig object. Een methode dog.decrease_energy(points) is gebonden aan precies één type. Je leert zien waarom dat uitmaakt.

Een losse functie zweeft β€” en kan overal op losgelaten worden

In sprint 5 schreef je losse functies. Dat is prima voor berekeningen die geen object nodig hebben. Maar zodra een functie de data van een object aanpast, begint het te wringen:

class Dog:
    def __init__(self, name):
        self.name   = name
        self.energy = 100

def decrease_energy(dog, points):   # losse functie
    dog.energy -= points

rex   = Dog("Rex")
bella = Dog("Bella")

decrease_energy(rex, 20)    # prima β€” bedoeld voor Dog
decrease_energy(bella, 10)  # ook prima

Zo ver lijkt het te kloppen. Maar de functie accepteert elk object als eerste argument. Python controleert het type niet:

class Robot:
    def __init__(self):
        self.energy = 50

robot = Robot()
decrease_energy("text", 5)     # AttributeError: 'str' object has no attribute 'energy'
decrease_energy(robot, 10)     # werkt stilletjes, maar een Robot is geen Dog!
Geen bewaker aan de deur. Een losse functie is een open deur. Elk object mag naar binnen, ook als het er niets te zoeken heeft. Een methode sluit die deur: hij wordt alleen aangeroepen op objecten van de juiste class.

Klik op een object

Selecteer een object en druk op Roep decrease_energy aan. Python probeert het β€” kijk wat er mis gaat bij het verkeerde type.

Losse functie
def decrease_energy(dog, points): dog.energy -= points

Klik op een object hieronder om het te selecteren:

πŸ•
rex
Dog-object
πŸ€–
robot
Robot-object
πŸ“
"text"
str
πŸ”’
42
int
De fix (taak 2): Verplaats decrease_energy naar binnen de class als methode. Dan schrijf je rex.decrease_energy(20) β€” en Python weet dat rex een Dog is, vΓ³Γ³rdat de methode begint.
>>> Oefenomgeving: Python REPL Simulator

Voel het probleem van de losse functie zelf.

  1. rex = Dog("Rex")
  2. bella = Dog("Bella")
  3. decrease_energy(rex, 20) β€” werkt prima.
  4. rex.energy β€” wat is de waarde?
  5. decrease_energy("text", 5) β€” wat doet Python?
  6. robot = Robot()
  7. decrease_energy(robot, 10) β€” werkt het? Is dit wat je wil?
  8. robot.energy β€” bekijk de energie van de robot na de aanroep.
Python 3.11 REPL Simulator Β· typ een commando en druk op Enter. # class Dog: def __init__(self, name): self.name=name; self.energy=100 # class Robot: def __init__(self): self.energy=50 # def decrease_energy(dog, points): dog.energy -= points
>>> 
🧩

Jouw opdracht: losse functie op het verkeerde object

Je bouwt een kleine webwinkel. Je schrijft bewust een losse functie en test hem daarna op meerdere objecten β€” zodat je ziet wat er misgaat. Je hebt twee classes nodig. Zet elke class in een eigen bestand, zoals je in sprint 6 zag. De losse functie en je tests komen in main.py.

  1. Maak in product.py een class Product met self.name en self.stock = 10.
  2. Schrijf in main.py een losse functie decrease_stock(product, amount) die product.stock -= amount doet.
  3. Maak twee Product-objecten: apple en pear.
  4. Roep decrease_stock(apple, 3) aan. Print apple.stock en pear.stock β€” welke is veranderd?
  5. Maak nu in warehouse.py een tweede class Warehouse met self.stock = 100. Maak in main.py warehouse = Warehouse() en roep decrease_stock(warehouse, 4) aan. Print warehouse.stock. Geeft Python een foutmelding? Wat is het gevaar hiervan?
  6. Roep ook decrease_stock("text", 4) aan. Wat zegt Python nu?
  7. Schrijf in commentaar op: waarom is dit een probleem bij een groter project?

Acceptatiecriteria

  • decrease_stock(apple, 3) past alleen apple.stock aan.
  • Je hebt aangetoond dat de functie ook werkt op een Warehouse zonder foutmelding.
  • Je hebt de AttributeError van de tekst gezien en benoemd.
  • In commentaar staat waarom dit een gevaar is.
  • Elke class staat in een eigen bestand en main.py importeert ze.