Magische methoden in Python

Magische methoden in Python

Dit artikel legt de magische methoden in Python uit.

YouTube Video

Magische methoden in Python

Magische methoden (speciale methoden) in Python zijn speciaal benoemde methoden die worden gebruikt om klassen unieke gedragingen te geven. Ze worden bijvoorbeeld gekenmerkt doordat ze tussen dubbele underscores staan (dunders), zoals __init__ en __str__. Daarom worden ze ook wel dunder-methoden genoemd.

Door magische methoden te definiëren, kun je het standaardgedrag van klassen aanpassen. Door bijvoorbeeld __add__ te definiëren, kun je het gedrag van de +-operator veranderen.

Magische methoden voor initialisatie en stringrepresentatie

__init__: Initialisatiemethode

De __init__-methode is een constructor die automatisch wordt aangeroepen wanneer een instantie wordt aangemaakt.

1class Person:
2    def __init__(self, name, age):
3        self.name = name
4        self.age = age
5
6person = Person("Alice", 30)
7print(person.name)  # Alice

__str__: Menselijk leesbare stringrepresentatie

De __str__-methode geeft een menselijk leesbare stringrepresentatie terug. Deze wordt aangeroepen door print() en str().

1class Person:
2    def __init__(self, name):
3        self.name = name
4
5    def __str__(self):
6        return f"Person: {self.name}"
7
8person = Person("Bob")
9print(person)  # Person: Bob

__repr__: Debuggerichte stringrepresentatie

De __repr__-methode geeft een stringrepresentatie terug voor debuggingdoeleinden. Deze wordt gebruikt door repr() en bij het weergeven in de interpreter.

1class Person:
2    def __init__(self, name):
3        self.name = name
4
5    def __repr__(self):
6        return f"Person(name={self.name!r})"
7
8person = Person("Eve")
9print(repr(person))  # Person(name='Eve')

Aritmetische operatoren overbelasten

__add__: +-operator

Door magische methoden te gebruiken kunnen aritmetische operatoren worden overbelast. De __add__-methode maakt het bijvoorbeeld mogelijk om de +-operator te overbelasten.

 1class Vector:
 2    def __init__(self, x, y):
 3        self.x = x
 4        self.y = y
 5
 6    def __add__(self, other):
 7        return Vector(self.x + other.x, self.y + other.y)
 8
 9    def __repr__(self):
10        return f"Vector({self.x}, {self.y})"
11
12    # Other arithmetic magic methods:
13    # def __sub__(self, other):       # Subtraction (-)
14    # def __mul__(self, other):       # Multiplication (*)
15    # def __truediv__(self, other):   # True division (/)
16    # def __floordiv__(self, other):  # Floor division (//)
17    # def __mod__(self, other):       # Modulo (%)
18    # def __pow__(self, other):       # Exponentiation (**)
19
20v1 = Vector(1, 2)
21v2 = Vector(3, 4)
22print(v1 + v2)  # Vector(4, 6)

Andere magische aritmetische methoden zijn onder andere:.

Methode Operator
__add__ +
__sub__ -
__mul__ *
__truediv__ /
__floordiv__ //
__mod__ %
__pow__ **

Vergelijkingsoperatoren aanpassen

Je kunt ook vergelijkingsoperatoren overbelasten. De __eq__-methode overbelast bijvoorbeeld de gelijkheidsoperator.

 1class Box:
 2    def __init__(self, volume):
 3        self.volume = volume
 4
 5    def __eq__(self, other):
 6        return self.volume == other.volume
 7
 8    def __lt__(self, other):
 9        return self.volume < other.volume
10
11    # Comparison magic methods:
12    # def __eq__(self, other):  # Equal to (==)
13    # def __ne__(self, other):  # Not equal to (!=)
14    # def __lt__(self, other):  # Less than (<)
15    # def __le__(self, other):  # Less than or equal to (<=)
16    # def __gt__(self, other):  # Greater than (>)
17    # def __ge__(self, other):  # Greater than or equal to (>=)
18
19b1 = Box(100)
20b2 = Box(200)
21
22print(b1 == b2)  # False
23print(b1 < b2)   # True

Er zijn ook de volgende magische methoden:. Deze magische methoden definiëren vergelijkingen zoals gelijkheid en ordening tussen objecten.

Operator Magische methode
== __eq__
!= __ne__
< __lt__
<= __le__
> __gt__
>= __ge__

Magische methoden voor container-types

Je kunt klassen maken die zich gedragen als lijsten of woordenboeken.

__len__: Het aantal elementen opvragen

De __len__ methode is een magische methode die het aantal elementen teruggeeft.

1class Basket:
2    def __init__(self, items):
3        self.items = items
4
5    def __len__(self):
6        return len(self.items)
7
8basket = Basket(["apple", "banana"])
9print(len(basket))  # 2

__getitem__: Index-toegang

De __getitem__-methode wordt aangeroepen wanneer index-toegang wordt gebruikt.

1class Basket:
2    def __init__(self, items):
3        self.items = items
4
5    def __getitem__(self, index):
6        return self.items[index]
7
8basket = Basket(["apple", "banana"])
9print(basket[1])  # banana

__setitem__ en __delitem__: Schrijven en verwijderen

De methoden __setitem__ en __delitem__ worden aangeroepen bij het schrijven of verwijderen van items.

 1class Basket:
 2    def __init__(self, items):
 3        self.items = items
 4
 5    def __setitem__(self, index, value):
 6        self.items[index] = value
 7
 8    def __delitem__(self, index):
 9        del self.items[index]
10
11basket = Basket(["apple", "banana"])
12basket[1] = "grape"
13del basket[0]
14print(basket.items)  # ['grape']

Magische methoden voor iteratie

Om een object herhaalbaar (iterabel) te maken in een for-lus, implementeer je het volgende:.

__iter__ en __next__

 1class Counter:
 2    def __init__(self, limit):
 3        self.limit = limit
 4        self.current = 0
 5
 6    def __iter__(self):
 7        return self
 8
 9    def __next__(self):
10        if self.current >= self.limit:
11            raise StopIteration
12        self.current += 1
13        return self.current
14
15for num in Counter(3):
16    print(num)
17# Output:
18# 1
19# 2
20# 3

Contextmanager (with-statement)

Door de methoden __enter__ en __exit__ te definiëren, kun je voor- en nabewerking voor het with-statement implementeren.

 1class FileOpener:
 2    def __init__(self, filename):
 3        self.filename = filename
 4
 5    def __enter__(self):
 6        self.file = open(self.filename, 'r')
 7        return self.file
 8
 9    def __exit__(self, exc_type, exc_val, exc_tb):
10        self.file.close()
11
12with FileOpener("example.txt") as f:
13    content = f.read()
14    print(content)

Aanroepbare objecten: __call__

Door de methode __call__ te definiëren, kun je een instantie aanroepbaar maken als een functie.

1class Greeter:
2    def __init__(self, greeting):
3        self.greeting = greeting
4
5    def __call__(self, name):
6        return f"{self.greeting}, {name}!"
7
8hello = Greeter("Hello")
9print(hello("Alice"))  # Hello, Alice!

Samenvatting

Magische methoden in Python zijn een krachtige manier om natuurlijk en intuïtief gedrag aan klassen toe te voegen. Elke methode heeft een duidelijk doel en door ze correct te implementeren kun je flexibeler en meer 'Pythonic' code schrijven.

Magische methoden dienen als een 'onzichtbare interface' die ondersteunt hoe Python-objecten op de achtergrond met elkaar interageren en zich gedragen.

Je kunt het bovenstaande artikel volgen met Visual Studio Code op ons YouTube-kanaal. Bekijk ook het YouTube-kanaal.

YouTube Video