Direct naar de hoofdinhoud
Module 7 · Les 3 van 427/36 in de cursus~12 min
Modulelessen (3/4)

Speciale methoden (dunder)

Speciale methoden (ook wel dunder-methoden genoemd omdat ze beginnen en eindigen met een dubbel onderstrepingsteken: __name__) zijn de haken waarmee je objecten kunt plaatsen integreren met de taal: tekstweergave, vergelijking met ==, ondersteuning voor len(), in, operators, enz.

Je hebt er al een gebruikt: __init__.

__str__ en __repr__

Zij bepalen wat er verschijnt met print() en in de REPL.

Python
class Punto:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __repr__(self):
        return f"Punto({self.x}, {self.y})"

    def __str__(self):
        return f"({self.x}, {self.y})"

p = Punto(3, 4)
str(p)        # '(3, 4)'        — per umani
repr(p)       # 'Punto(3, 4)'   — per debugger / dev
print(p)      # '(3, 4)'
p             # Punto(3, 4)     in REPL → repr
[p, p]        # [Punto(3, 4), Punto(3, 4)]   — sempre repr nei contenitori

Als je alleen __repr__ definieert, gebruikt Python dit ook als fallback voor BESCHERMD_INLINE_14.

__eq__: herdefiniëren van ==

Standaard vergelijkt a == b de identifiers van de objecten (is), niet hun inhoud. Voor structurele vergelijking definieert u __eq__:

Python
class Punto:
    def __init__(self, x, y):
        self.x, self.y = x, y

    def __eq__(self, other):
        if not isinstance(other, Punto):
            return NotImplemented
        return (self.x, self.y) == (other.x, other.y)

Punto(1, 2) == Punto(1, 2)    # True
Punto(1, 2) == Punto(3, 4)    # False

Er wordt NotImplemented geretourneerd (een speciaal trefwoord, niet False!) wanneer de typen zijn niet vergelijkbaar is de juiste praktijk: Python zal het dan proberen met de __eq__ van een andere operand.

__len__: ondersteuning voor len()

Python
class Cesto:
    def __init__(self):
        self.frutti = []

    def __len__(self):
        return len(self.frutti)

c = Cesto()
c.frutti.append("mela")
len(c)        # 1
bool(c)       # True (len > 0)

Door __len__ te definiëren, krijgt u ook gratis de boolean: een object met len() == 0 wordt vals.

Andere nuttige dunders (overzicht)

  • __add__(self, other) → herdefinieert +
  • __lt__, __le__, __gt__, __ge__ → vergelijkingsoperatoren
  • __contains__(self, item) → ondersteunt item in self
  • __iter__ + __next__ → maakt het object itereerbaar
  • __getitem__(self, key) → ondersteunt self[key]
  • __hash__ → moet een dicteertoets / set-element zijn

Jouw beurt

Oefening#python.m7.l3.e1
Pogingen: 0Laden…

Definieer `Geld` met __init__(zelf, bedrag, valuta) en __str__ die `f'{bedrag} {valuta}'` retourneert. Creëer `s = Money(42, 'EUR')` en evalueer `str(s)`.

Editor laden…
Toon hint

f-snaar in __str__.

Oplossing beschikbaar na 3 pogingen

Oefening beoordelen

Oefening#python.m7.l3.e2
Pogingen: 0Laden…

Definieer 'Paar' met __init__(self, a, b) en __eq__ op basis van de structurele vergelijking van (a, b). Evalueer `Paar(1, 2) == Paar(1, 2)`.

Editor laden…
Toon hint

Vergelijk de tupels (self.a, self.b) == (other.a, other.b).

Oplossing beschikbaar na 3 pogingen

Extra uitdaging

Oefening#python.m7.l3.e3
Pogingen: 0Laden…

Definieer een klasse 'Boek' met een constructor met 'titel' en 'auteur'. Definieer de speciale methode \`__str__(self)\` zodat deze de string \`"Titel op auteur"\` retourneert (bijvoorbeeld \`'1984 door George Orwell'\`). Instantieer een boek en evalueer \`str(book)\`.

Editor laden…
Toon hint

Gebruik f"{self.title} door {self.author}" in def __str__(self):.

Oplossing beschikbaar na 3 pogingen