Магические методы Python позволяют изменять поведение объектов при использовании стандартных операторов. Например, метод __add__
отвечает за поведение объекта при использовании оператора сложения +
.
__add__
:class MyString:
def __init__(self, value):
self.value = value
def __add__(self, other):
return self.value + other
Создав экземпляр класса, можно складывать объекты как строки:
s = MyString("Hello")
print(s + " World") # Выведет: "Hello World"
При создании собственного класса, его экземпляры изначально не могут участвовать в операциях сложения. Если попытаться сложить объект с чем-то, Python выдаст ошибку:
class BankAccount:
def __init__(self, balance):
self.balance = balance
acc = BankAccount(100)
print(acc + 50) # TypeError: unsupported operand type(s) for +: 'BankAccount' and 'int'
Для исправления этой проблемы, нужно определить метод __add__
в классе:
class BankAccount:
def __init__(self, balance):
self.balance = balance
def __add__(self, other):
if isinstance(other, (int, float)):
return BankAccount(self.balance + other)
raise TypeError("Можно сложить только с числом или другим банковским счетом")
Теперь можно складывать объект с числами:
acc = BankAccount(100)
new_acc = acc + 50
print(new_acc.balance) # Выведет: 150
Однако если поменять местами операнды (50 + acc
), мы снова получим ошибку.
__radd__
Метод __radd__
отвечает за операции сложения, когда экземпляр класса стоит справа от оператора сложения:
class BankAccount:
def __init__(self, balance):
self.balance = balance
def __add__(self, other):
if isinstance(other, (int, float)):
return BankAccount(self.balance + other)
raise TypeError("Можно сложить только с числом")
def __radd__(self, other):
return self.__add__(other)
Теперь операция 50 + acc
тоже будет работать:
new_acc = 50 + acc
print(new_acc.balance) # Выведет: 150
В Python для каждой арифметической операции существует соответствующий магический метод. Ниже приведены основные из них:
Название метода | Операция |
---|---|
__sub__(self, other) | Операция вычитания с использованием оператора - |
__mul__(self, other) | Операция умножения с использованием оператора * |
__truediv__(self, other) | Операция обычного деления с использованием оператора / |
__floordiv__(self, other) | Операция целочисленного деления с использованием // |
__mod__(self, other) | Операция получения остатка от деления с использованием % |
__divmod__(self, other) | Деление с остатком, реализует функцию divmod(...) |
__pow__(self, other) | Возведение в степень с использованием оператора ** |
__lshift__(self, other) | Операция сдвига влево с использованием оператора << |
__rshift__(self, other) | Операция сдвига вправо с использованием оператора >> |
__and__(self, other) | Операция побитового И с использованием оператора & |
__xor__(self, other) | Операция побитового исключающего ИЛИ с использованием оператора ^ |
__or__(self, other) | Операция побитового ИЛИ с использованием оператора ` |
Кроме обычных магических методов, существуют отраженные версии, которые вызываются, когда левый операнд не реализует соответствующий метод:
Название метода | Операция |
---|---|
__radd__(self, other) | Операция сложения с перестановкой операндов |
__rsub__(self, other) | Операция вычитания с перестановкой операндов |
__rmul__(self, other) | Операция умножения с перестановкой операндов |
__rtruediv__(self, other) | Операция деления с перестановкой операндов |
__rfloordiv__(self, other) | Операция целочисленного деления с перестановкой операндов |
__rmod__(self, other) | Операция остатка от деления с перестановкой операндов |
__rdivmod__(self, other) | Операция divmod с перестановкой операндов |
__rpow__(self, other) | Возведение в степень с перестановкой операндов |
__rlshift__(self, other) | Операция сдвига влево с перестановкой операндов |
__rrshift__(self, other) | Операция сдвига вправо с перестановкой операндов |
__rand__(self, other) | Побитовое И с перестановкой операндов |
__rxor__(self, other) | Побитовое исключающее ИЛИ с перестановкой операндов |
__ror__(self, other) | Побитовое ИЛИ с перестановкой операндов |
Магические методы позволяют настраивать поведение ваших классов при работе с операторами. Правильное использование таких методов, как __add__
, __radd__
и других, позволяет создавать более гибкие и адаптируемые классы, взаимодействующие с различными операциями корректно и предсказуемо.