Python Mastery – From Basics to Brilliance / Object-Oriented Programming (OOP)

Magic Methods

class Box:
    def __init__(self, items):
        self.items = list(items)

    def __str__(self):
        return f"Box with {len(self.items)} items"

    def __repr__(self):
        return f"Box({self.items!r})"

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

    def __add__(self, other):
        return Box(self.items + other.items)

    def __eq__(self, other):
        return self.items == other.items

    def __getitem__(self, i):
        return self.items[i]

    def __setitem__(self, i, v):
        self.items[i] = v

    def __delitem__(self, i):
        del self.items[i]

    def __contains__(self, x):
        return x in self.items

    def __call__(self):
        return f"called! first item: {self.items[0]}"

    def __iter__(self):
        return iter(self.items)

    def __bool__(self):
        return len(self.items) > 0

    def __lt__(self, other):
        return len(self.items) < len(other.items)

    def __del__(self):
        print("Box destroyed")

🧠 What you're demonstrating

This is actually a great example for your Magic/Dunder Methods chapter:

Code you write

Python automatically calls

print(box1)

__str__()

repr(box1)

__repr__()

len(box1)

__len__()

box1 + box2

__add__()

box1 == box2

__eq__()

box1[0]

__getitem__()

box1[0] = x

__setitem__()

del box1[0]

__delitem__()

x in box1

__contains__()

box1()

__call__()

for x in box1

__iter__()

bool(box1)

__bool__()

box1 < box2

__lt__()

Object removed

__del__()