Skip to content
Programmeren in Python, leer de nieuwste technieken
Programmeren in PythonProgrammeren in Python
  • Home
  • Blog
  • Documentatie
  • Cursussen
Programmeren in PythonProgrammeren in Python
  • Home
  • Blog
  • Documentatie
  • Cursussen

Introductie

4
  • 1.1 Wat is Python?
  • 1.2 Python installatie
  • 1.2.1 Python installeren voor MacOS
  • 1.3 PyCharm Installatie

Basisprogrammering

6
  • 2.1 Python Basis: Variabelen, Datatypes en Operatoren
  • 2.2 Python if else (en elif)
  • 2.3 Python list (Array, Lijsten)
  • 2.4 Python Lussen: for loop, while loop, break, continue
  • 2.5 Python Functies: Definities, Parameters en Terugkeerwaarden
  • 2.6 Foutafhandeling: try, except, else, finally

Datatypes

13
  • 3.1 Introductie tot Geavanceerde Datatypes
  • 3.2 Python Tuple
  • 3.3 Python Set
  • 3.4 Python Dictionary
  • 3.5 Werken met Strings en String-methoden
  • 3.6 Collections Module: Krachtige Tools in Python
  • 3.7 Iterators en Generators
  • 3.8 List Comprehensions
  • 3.9 Geavanceerde Sortering
  • 3.10 Werken met Multi-dimensionale Data
  • 3.11 Typing en Datatypes
  • 3.12 Itertools voor Geavanceerde Iteraties
  • 3.13 Data Conversies

Modules

8
  • 4.1 Wat zijn Modules en Waarom zijn ze Belangrijk?
  • 4.2 Werken met Ingebouwde Modules
  • 4.3 Installeren en Gebruiken van Externe Pakketten
  • 4.4 Eigen Modules Maken
  • 4.5 Introductie tot Pakketten
  • 4.6 Importeren en Namespaces Begrijpen
  • 4.7 Geavanceerd: Relatief Importeren
  • 4.8 Organiseren van Grotere Projecten

Data Analyse

3
  • 5.1 Python Dataframe en Data Opschonen met Pandas
  • 5.2 Python Pandas Basisstatistieken en Data-analyse
  • 5.3 Python Numpy (NpArray): De Kracht van Numerieke Berekeningen

Webontwikkeling

5
  • 7.1 Inleiding tot Webontwikkeling
  • 7.2 HTTP-Verzoeken met requests: Communiceren met het Web
  • 7.3 Webscraping met BeautifulSoup: Data van het Web Halen als er geen APIs zijn
  • 7.4 Python Flask, een webserver & API tutorial
  • 7.5 WSGI & WebOb

Deploy

1
  • Deploy met Supervisor op Ubuntu

Object Georiënteerd Programmeren

8
  • Wat is Objectgeoriënteerd Programmeren (OOP) in Python?
  • Python class & object maken
  • self en __init__ uitgelegd (met voorbeelden)
  • Attributen afschermen: @property (getters/setters)
  • Overerving in Python + super() (en wanneer je het beter níet doet)
  • Dunder methods: __str__, __repr__, vergelijken (en waarom dit je OOP-code “Pythonic” maakt)
  • @dataclass: snelle nette classes (minder boilerplate, meer duidelijkheid)
  • OOP in de praktijk: design & structuur
View Categories
  • Home
  • Documentatie
  • Object Georiënteerd Programmeren
  • Dunder methods: __str__, __repr__, vergelijken (en waarom dit je OOP-code “Pythonic” maakt)

Dunder methods: __str__, __repr__, vergelijken (en waarom dit je OOP-code “Pythonic” maakt)

6 minuten leestijd

Na dit hoofdstuk snap je:

  • wat “dunder methods” zijn (double underscore),
  • het verschil tussen __str__ en __repr__ (en wanneer welke gebruikt wordt),
  • hoe je objecten kunt vergelijken met __eq__,
  • wat er gebeurt met ==, !=, in, sorteren, etc.
  • en je kent de valkuilen (recursie, inconsistenties, hash-problemen).

1. Wat zijn dunder methods? #

Dunder = duble underscore, zoals:

  • __init__
  • __str__
  • __repr__
  • __eq__

Dit zijn “speciale hooks” waarmee je Python vertelt:

  • hoe jouw object zich gedraagt als je het print,
  • hoe het zich laat vergelijken,
  • hoe het werkt in sets/dicts,
  • hoe het iteraties doet, enz.

Je hoeft ze niet te kennen om OOP te starten, maar:
zodra je eigen classes “netjes” moeten aanvoelen, worden ze goud waard.

2. __str__ vs __repr__ (het verschil dat iedereen door elkaar haalt) #

__str__ = bedoeld voor mensen #

Wordt gebruikt door:

  • print(obj)
  • str(obj)
__repr__ = bedoeld voor developers/debugging #

Wordt gebruikt door:

  • repr(obj)
  • in de Python shell / notebooks (weergave van objecten)
  • logging/debug output
  • containers: print([obj]) gebruikt vaak repr van elementen

Vuistregel die je kunt onthouden:

  • __str__: “mooi”
  • __repr__: “informatief / eenduidig”

Voorbeeld zonder dunders (onhandig)

class User:
    def __init__(self, name):
        self.name = name

u = User("Alice")
print(u)      # <__main__.User object at 0x...>
Python

Met __repr__ (debug-friendly)

class User:
    def __init__(self, name):
        self.name = name

    def __repr__(self):
        return f"User(name={self.name!r})"

u = User("Alice")
print(u)         # User(name='Alice')
print([u, u])    # [User(name='Alice'), User(name='Alice')]
Python

Waarom die !r?

{self.name!r} gebruikt repr(self.name) in plaats van str(self.name).
Dat is superhandig omdat je quotes ziet en speciale tekens duidelijk zijn.

Met __str__ (user-friendly output)

class User:
    def __init__(self, name):
        self.name = name

    def __repr__(self):
        return f"User(name={self.name!r})"

    def __str__(self):
        return self.name

u = User("Alice")
print(u)      # Alice  (str)
print(repr(u))# User(name='Alice') (repr)
Python

Tip: Als je maar één kiest: kies vaak __repr__ eerst.
__str__ is nice-to-have.

3. __eq__: objecten vergelijken met == #

Zonder __eq__ #

Python vergelijkt objecten standaard op identiteit (zelfde object in memory).

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

p1 = Point(1, 2)
p2 = Point(1, 2)
print(p1 == p2)  # False (standaard)
Python

Met __eq__ (waarde-vergelijking) #
class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

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

p1 = Point(1, 2)
p2 = Point(1, 2)
print(p1 == p2)  # True
Python

Waarom NotImplemented?

Als je other een ander type is, zeg je eigenlijk:

“Ik weet niet hoe ik hiermee moet vergelijken.”

Dan krijgt Python de kans om:

  • other.__eq__(p1) te proberen,
  • of netjes False te geven.

Dit is netter dan hard False retourneren.

4. Valkuil: __eq__ en __hash__ (sets/dicts) #

Dit is belangrijk:

  • Als je __eq__ definieert, verandert het idee van “gelijkheid”.
  • Voor gebruik in set of als key in dict heb je ook een stabiele __hash__ nodig.
  • Python zet soms automatisch __hash__ = None als je __eq__ definieert, om je te beschermen tegen bugs.
Waarom? #

Een set/dict gebruikt hashes om snel te zoeken.
Als twee objecten “gelijk” zijn (__eq__ True), moeten ze ook dezelfde hash hebben.

Als je object mutable is, is __hash__ gevaarlijk:

  • je wijzigt velden,
  • hash verandert,
  • object “verdwijnt” uit dict/set lookup.
Praktische regels #
  • Mutable value objects? Vaak: géén __hash__, dus niet als dict-key.
  • Immutable value objects? Dan kun je __hash__ wél goed doen.
  • Of gebruik @dataclass(frozen=True) later (hoofdstuk 6), die regelt dit netjes.

5. Voorbeeld: OrderLine (repr + eq) #

class OrderLine:
    def __init__(self, sku, qty):
        self.sku = sku
        self.qty = qty

    def __repr__(self):
        return f"OrderLine(sku={self.sku!r}, qty={self.qty})"

    def __eq__(self, other):
        if not isinstance(other, OrderLine):
            return NotImplemented
        return (self.sku, self.qty) == (other.sku, other.qty)

a = OrderLine("ABC", 2)
b = OrderLine("ABC", 2)

print(a)        # OrderLine(sku='ABC', qty=2)
print(a == b)   # True
Python

6. Extra (handig om te weten): __lt__ en sorteren #

Als je wil sorteren met sorted(...), kun je __lt__ (“less than”) implementeren.

class Student:
    def __init__(self, name, grade):
        self.name = name
        self.grade = grade

    def __repr__(self):
        return f"Student(name={self.name!r}, grade={self.grade})"

    def __lt__(self, other):
        if not isinstance(other, Student):
            return NotImplemented
        return self.grade < other.grade

students = [Student("A", 7.5), Student("B", 6.0)]
print(sorted(students))  # sorteert op grade
Python

(Je kunt ook vaak gewoon sorted(students, key=lambda s: s.grade) gebruiken; dat is meestal simpeler.)

7. Veelgemaakte fouten bij __repr__/__str__ #

Fout 1: recursie door jezelf te printen #
def __repr__(self):
    return f"{self}"  # ❌ self -> __str__/__repr__ -> loop
Python

Goed: bouw string uit velden (self.name, self._price, etc.).

Fout 2: te weinig informatie in __repr__ #
return "User()"
Python

Niet handig bij debugging. Zet minimaal de belangrijkste velden erin.

Nu je ook deze methodes kan toepassen is het handig om door te krijgen hoe je nette classes schrijft. Zie daarvoor het volgende hoofdstuk.

Updated on januari 4, 2026

What are your Feelings

Overerving in Python + super() (en wanneer je het beter níet doet)@dataclass: snelle nette classes (minder boilerplate, meer duidelijkheid)
Inhoudsopgave
  • 1. Wat zijn dunder methods?
  • 2. __str__ vs __repr__ (het verschil dat iedereen door elkaar haalt)
    • __str__ = bedoeld voor mensen
    • __repr__ = bedoeld voor developers/debugging
  • 3. __eq__: objecten vergelijken met ==
    • Zonder __eq__
    • Met __eq__ (waarde-vergelijking)
  • 4. Valkuil: __eq__ en __hash__ (sets/dicts)
    • Waarom?
    • Praktische regels
  • 5. Voorbeeld: OrderLine (repr + eq)
  • 6. Extra (handig om te weten): __lt__ en sorteren
  • 7. Veelgemaakte fouten bij __repr__/__str__
    • Fout 1: recursie door jezelf te printen
    • Fout 2: te weinig informatie in __repr__
Programmeren in Python

Leer python op je eigen tempo met mooie interactieve hedendaagse voorbeelden.

© Copyright 2026 Programmeren in Python.
Sign inSign up

Sign in

Don’t have an account? Sign up
Lost your password?

Sign up

Already have an account? Sign in