Python · The language, not just syntax

Which dunder methods matter most and what contracts do they carry?

Mediumdunder methodsprotocolsoperatorsUpdated Oct 2026
Quiz this track

Short answer

Dunder methods hook objects into Python protocols: __repr__ and __str__ for display, __eq__ and __hash__ for comparison, __len__ and __getitem__ for containers, and __call__ for callables.

Dunder methods are looked up on the type, not the instance, which is why special method behaviour is consistent for built-ins. Implementing them lets your objects work with len, ==, iteration, indexing, arithmetic, context managers and the with statement.

python
class Money:
    def __init__(self, cents, currency="USD"):
        self.cents = cents
        self.currency = currency

    def __repr__(self):
        return "Money(" + str(self.cents) + ", " + self.currency + ")"

    def __eq__(self, other):
        if not isinstance(other, Money):
            return NotImplemented
        return (self.cents, self.currency) == (other.cents, other.currency)

    def __hash__(self):
        return hash((self.cents, self.currency))

    def __add__(self, other):
        if self.currency != other.currency:
            raise ValueError("currency mismatch")
        return Money(self.cents + other.cents, self.currency)

print(Money(500) + Money(250))
Returning NotImplemented lets Python try the reflected operation instead of raising immediately.

Contracts to respect

  • __repr__ should be unambiguous and ideally evaluable; __str__ is for users
  • If you define __eq__, define __hash__ too or the object becomes unhashable
  • Equal objects must have equal hashes, or dict and set behaviour breaks
  • __getitem__ should raise IndexError for out-of-range access so iteration works

Do not overload operators with surprising meanings. A __add__ that mutates one operand or performs I/O will confuse anyone reading the call site. When in doubt, a named method communicates intent better than an operator.

Defining __eq__ sets __hash__ to None unless you define it explicitly, because mutable value objects are usually not safe dictionary keys.

Follow-ups you should expect

Interviewers use these to check whether the first answer was understanding or memorisation.

  1. 1What is the difference between __repr__ and __str__?
  2. 2What happens if you define __eq__ without __hash__?
  3. 3Why return NotImplemented instead of raising TypeError?
  4. 4How does __getitem__ make an object iterable?

Say it in the interview

Dunder methods integrate objects with Python protocols. I implement __repr__ for developers, __str__ for users, and __eq__ with a matching __hash__ so equal values behave correctly in dicts and sets. For operators I return NotImplemented on unsupported types so Python can try the reflected operation. I avoid operator overloading when a named method would communicate the behaviour more clearly.

Use this as a model, not a script. Saying it in your own words is what makes it survive follow-up pressure.

Related questions

Reading is step one

Now say it out loud.

Understanding an answer and delivering it under pressure are different skills. Rehearse this topic in a live Python mock interview and get scored feedback on depth, clarity and confidence.