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.