1. Пытается отработать x + y. Вызывается
x.__add__(y)
(или, что то же самое,
Commuter5.__add__(x, y)
).
2. Внутри кода __add__() вычисляется выражение
self.value + other
. Вызывается
self.value.__add__(other)
(
int.__add__(self.value, other)
, так как self.value содержит целое число).
3. int понятия не имеет, что такое Commuter5 и как с ним складываться. Его __add__() возвращает
NotImplemented. Питон понимает, что от int помощи не дождёшься.
4. Поэтому вызывается
other.__radd__(self.value)
.
5. Внутри этого метода вычисляется выражение
self.value + x
. В данном случае x - это self.value для первого операнда, т.е. число. self.value - тоже число. int знает, как складываться с другим int, и выражение даёт int.
6. Отрабатывает конструктор Commuter5() внутри __radd__(). Создаётся новый экземпляр класса, и возвращается как результат вызова __radd__().
7. Отрабатывает конструктор Commuter5() внутри __add__(). Результат (ещё один экземпляр Commuter5) возвращается наружу.
8. z присваивается результат, возвращённый вызовом __add__().
По-моему, в коде ошибка, так как в результате у нас окажется, что внутри Commuter5() будет ещё один объект Commuter5(), внутри которого уже будет сумма. Ты можешь проверить это достаточно просто:
print(type(z.value))
Если выведет
<class Commuter5 ...>
- значит, я прав.
Чтобы это исправить, операторы __add__() и __radd__() должны проверять, что получилось в результате суммирования, и не заворачивать результат в Commuter5() еще раз.