← Назад к вопросам

Что такое служебный метод dict?

2.7 Senior🔥 91 комментариев
#FastAPI и Flask#Soft Skills

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Служебные методы dict в Python

Служебные методы dict (dunder methods или magic methods) — это специальные методы, которые начинаются и заканчиваются двойными подчеркиваниями (__). Они позволяют объектам работать с операторами Python и стандартными функциями, как если бы они были встроенными типами.

Основные dunder методы dict

init и new

class MyDict:
    def __init__(self, **kwargs):
        self.data = kwargs
    
    def __new__(cls, *args, **kwargs):
        # Вызывается перед __init__
        instance = super().__new__(cls)
        return instance

d = MyDict(name="Alice", age=30)
print(d.data)  # {name: Alice, age: 30}

getitem и setitem

Позволяют использовать индексацию dict[key]:

class CustomDict:
    def __init__(self):
        self.storage = {}
    
    def __getitem__(self, key):
        # d[key]
        print(f"Получаю значение для {key}")
        return self.storage.get(key)
    
    def __setitem__(self, key, value):
        # d[key] = value
        print(f"Устанавливаю {key}={value}")
        self.storage[key] = value

d = CustomDict()
d["name"] = "Alice"      # Вызовет __setitem__
value = d["name"]       # Вызовет __getitem__

delitem

Позволяет удалять элементы через del dict[key]:

class CustomDict:
    def __init__(self):
        self.storage = {}
    
    def __delitem__(self, key):
        # del d[key]
        print(f"Удаляю {key}")
        del self.storage[key]

d = CustomDict()
d.storage["name"] = "Alice"
del d["name"]  # Вызовет __delitem__

len

Позволяет использовать len(dict):

class CustomDict:
    def __init__(self):
        self.storage = {}
    
    def __len__(self):
        return len(self.storage)
    
    def __setitem__(self, key, value):
        self.storage[key] = value

d = CustomDict()
d["a"] = 1
d["b"] = 2
print(len(d))  # 2

contains

Позволяет использовать in оператор:

class CustomDict:
    def __init__(self):
        self.storage = {}
    
    def __contains__(self, key):
        return key in self.storage
    
    def __setitem__(self, key, value):
        self.storage[key] = value

d = CustomDict()
d["name"] = "Alice"
print("name" in d)  # True
print("age" in d)   # False

iter и next

Позволяют итерировать по объекту:

class CustomDict:
    def __init__(self, **kwargs):
        self.data = kwargs
        self.keys_list = list(kwargs.keys())
        self.index = 0
    
    def __iter__(self):
        return iter(self.data)
    
    def __next__(self):
        if self.index >= len(self.keys_list):
            raise StopIteration
        key = self.keys_list[self.index]
        self.index += 1
        return key

d = CustomDict(name="Alice", age=30)
for key in d:
    print(key)  # name, age

Арифметические операции

add, sub, mul

class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    
    def __add__(self, other):
        return Vector(self.x + other.x, self.y + other.y)
    
    def __sub__(self, other):
        return Vector(self.x - other.x, self.y - other.y)
    
    def __mul__(self, scalar):
        return Vector(self.x * scalar, self.y * scalar)
    
    def __repr__(self):
        return f"Vector({self.x}, {self.y})"

v1 = Vector(1, 2)
v2 = Vector(3, 4)
print(v1 + v2)      # Vector(4, 6)
print(v1 - v2)      # Vector(-2, -2)
print(v1 * 2)       # Vector(2, 4)

Операторы сравнения

eq, lt, gt

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    def __eq__(self, other):
        return self.age == other.age
    
    def __lt__(self, other):
        return self.age < other.age
    
    def __gt__(self, other):
        return self.age > other.age
    
    def __repr__(self):
        return f"Person({self.name}, {self.age})"

p1 = Person("Alice", 30)
p2 = Person("Bob", 25)
print(p1 == p2)  # False
print(p1 > p2)   # True
print(p2 < p1)   # True

people = [p1, p2]
people.sort()  # Использует __lt__
print(people)  # [Person(Bob, 25), Person(Alice, 30)]

str и repr

class Product:
    def __init__(self, name, price):
        self.name = name
        self.price = price
    
    def __str__(self):
        # Для пользователя (print)
        return f"{self.name} стоит {self.price} руб."
    
    def __repr__(self):
        # Для разработчика (интерпретатор)
        return f"Product({self.name}, {self.price})"

p = Product("Книга", 500)
print(str(p))   # Книга стоит 500 руб.
print(repr(p))  # Product(Книга, 500)
print(p)        # Вызывает __str__

call

Делает объект вызываемым как функция:

class Multiplier:
    def __init__(self, factor):
        self.factor = factor
    
    def __call__(self, x):
        return x * self.factor

multiply_by_3 = Multiplier(3)
print(multiply_by_3(5))     # 15
print(multiply_by_3(10))    # 30

enter и exit

Позволяют использовать объект в with блоке:

class FileManager:
    def __init__(self, filename, mode):
        self.filename = filename
        self.mode = mode
        self.file = None
    
    def __enter__(self):
        self.file = open(self.filename, self.mode)
        return self.file
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        if self.file:
            self.file.close()
        return False  # Не подавляем исключения

with FileManager("test.txt", "w") as f:
    f.write("Hello")
# Файл автоматически закроется

hash и eq для dict ключей

class User:
    def __init__(self, id, name):
        self.id = id
        self.name = name
    
    def __hash__(self):
        return hash(self.id)
    
    def __eq__(self, other):
        return self.id == other.id

user1 = User(1, "Alice")
user2 = User(1, "Alice")

users_dict = {user1: "Info1"}
print(users_dict[user2])  # Info1 (работает, потому что hash и eq согласованы)

getattr и setattr

class DynamicObject:
    def __getattr__(self, name):
        # Вызывается если атрибута нет
        return f"Атрибут {name} не существует"
    
    def __setattr__(self, name, value):
        # Вызывается при присваивании
        print(f"Устанавливаю {name}={value}")
        super().__setattr__(name, value)

obj = DynamicObject()
obj.x = 5              # Вызовет __setattr__
print(obj.y)           # Вызовет __getattr__

Резюме

Служебные методы dict — это мощный инструмент для создания объектов, которые работают как встроенные типы. Они позволяют переопределять поведение операторов, сравнений, индексации и многого другого. Понимание dunder методов критично для написания Pythonic кода и создания удобных API.

Что такое служебный метод dict? | PrepBro