Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Магические методы (Dunder Methods) в Python
Определение
Магические методы (Magic Methods) или Dunder Methods (двойные подчеркивания) — это специальные методы в Python, которые начинаются и заканчиваются двойным подчеркиванием __. Они вызываются автоматически в определенных ситуациях.
Примеры: __init__, __str__, __repr__, __add__
Основные магические методы
1. __init__ (Конструктор)
class TestUser:
def __init__(self, name, email):
self.name = name
self.email = email
user = TestUser("Alice", "alice@test.com") # Вызывает __init__
2. __str__ (Строковое представление для пользователя)
class TestResult:
def __init__(self, test_name, passed):
self.test_name = test_name
self.passed = passed
def __str__(self):
status = "PASSED" if self.passed else "FAILED"
return f"{self.test_name}: {status}"
result = TestResult("test_login", True)
print(result) # Вызывает __str__
# Вывод: test_login: PASSED
3. __repr__ (Представление для разработчика)
class TestCase:
def __init__(self, test_id):
self.test_id = test_id
def __repr__(self):
return f"TestCase(test_id={self.test_id})"
tc = TestCase("TC001")
print(repr(tc)) # TestCase(test_id=TC001)
print([tc]) # [TestCase(test_id=TC001)]
4. __len__ (Длина объекта)
class TestSuite:
def __init__(self, tests):
self.tests = tests
def __len__(self):
return len(self.tests)
suite = TestSuite(["test1", "test2", "test3"])
print(len(suite)) # 3
5. __getitem__ (Доступ по индексу)
class TestResults:
def __init__(self, results):
self.results = results
def __getitem__(self, index):
return self.results[index]
results = TestResults(["PASS", "FAIL", "PASS"])
print(results[0]) # PASS
print(results[1]) # FAIL
6. __setitem__ (Установка значения по индексу)
class TestScores:
def __init__(self):
self.scores = {}
def __setitem__(self, test_id, score):
self.scores[test_id] = score
scores = TestScores()
scores["TC001"] = 95 # Вызывает __setitem__
print(scores.scores) # {"TC001": 95}
7. __contains__ (Оператор in)
class TestRegistry:
def __init__(self, test_ids):
self.test_ids = test_ids
def __contains__(self, test_id):
return test_id in self.test_ids
registry = TestRegistry(["TC001", "TC002", "TC003"])
if "TC001" in registry: # Вызывает __contains__
print("Test found")
8. Арифметические операторы
class TestScore:
def __init__(self, value):
self.value = value
def __add__(self, other):
return TestScore(self.value + other.value)
def __sub__(self, other):
return TestScore(self.value - other.value)
def __mul__(self, number):
return TestScore(self.value * number)
def __truediv__(self, number):
return TestScore(self.value / number)
score1 = TestScore(100)
score2 = TestScore(80)
result = score1 + score2 # Вызывает __add__
9. Операторы сравнения
class User:
def __init__(self, user_id):
self.user_id = user_id
def __eq__(self, other):
return self.user_id == other.user_id
def __lt__(self, other):
return self.user_id < other.user_id
def __le__(self, other):
return self.user_id <= other.user_id
def __gt__(self, other):
return self.user_id > other.user_id
user1 = User(1)
user2 = User(2)
print(user1 == user2) # False
print(user1 < user2) # True
10. __call__ (Объект как функция)
class TestExecutor:
def __init__(self, test_name):
self.test_name = test_name
def __call__(self, *args, **kwargs):
print(f"Executing {self.test_name}")
return True
executor = TestExecutor("test_login")
result = executor() # Вызывает __call__
# Вывод: Executing test_login
11. __enter__ и __exit__ (Context Manager)
class DatabaseConnection:
def __enter__(self):
print("Opening connection")
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print("Closing connection")
return False
with DatabaseConnection() as db:
print("Using connection")
# Вывод:
# Opening connection
# Using connection
# Closing connection
12. __iter__ (Итератор)
class TestQueue:
def __init__(self, tests):
self.tests = tests
self.index = 0
def __iter__(self):
return self
def __next__(self):
if self.index >= len(self.tests):
raise StopIteration
result = self.tests[self.index]
self.index += 1
return result
queue = TestQueue(["test1", "test2", "test3"])
for test in queue:
print(test)
# Выведет: test1, test2, test3
13. __del__ (Деструктор)
class TestEnvironment:
def __init__(self, name):
self.name = name
print(f"Creating {name}")
def __del__(self):
print(f"Destroying {self.name}")
env = TestEnvironment("test_env")
del env # Вызывает __del__
Таблица основных магических методов
| Метод | Использование | Пример |
|---|---|---|
__init__ | Конструктор | obj = Class() |
__str__ | Строка для пользователя | print(obj) |
__repr__ | Строка для разработчика | repr(obj) |
__len__ | Длина | len(obj) |
__getitem__ | По индексу | obj[0] |
__setitem__ | Установка | obj[0] = value |
__contains__ | Проверка | item in obj |
__add__ | Сложение | obj1 + obj2 |
__sub__ | Вычитание | obj1 - obj2 |
__call__ | Как функция | obj() |
__enter__ | Начало контекста | with obj: |
__exit__ | Конец контекста | with obj: |
__iter__ | Итератор | for x in obj: |
__eq__ | Равно | obj1 == obj2 |
__lt__ | Меньше | obj1 < obj2 |
Практический пример для QA
class TestReport:
def __init__(self, name, total, passed):
self.name = name
self.total = total
self.passed = passed
def __str__(self):
return f"{self.name}: {self.passed}/{self.total}"
def __repr__(self):
return f"TestReport({self.name}, {self.total}, {self.passed})"
def __len__(self):
return self.total
def __add__(self, other):
return TestReport(
f"{self.name} + {other.name}",
self.total + other.total,
self.passed + other.passed
)
report1 = TestReport("Suite1", 10, 9)
report2 = TestReport("Suite2", 5, 5)
print(report1) # Suite1: 9/10
print(len(report1)) # 10
print(report1 + report2) # Suite1 + Suite2: 14/15
Резюме
Магические методы позволяют:
- Переопределять встроенные операции (
+,-,==,<) - Интегрировать объекты в Python стандартные функции
- Создавать более интуитивный API
- Реализовать context managers и итераторы
Используйте их для создания удобных интерфейсов в тестовом коде.