Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Разница между init и dir
Это два фундаментально разных магических метода в Python, которые выполняют совершенно разные роли в жизненном цикле объекта и его отражении (introspection).
init — Инициализатор объекта
init вызывается сразу после создания объекта (после new) и служит для инициализации состояния экземпляра:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
self.email = None
person = Person("Alice", 30) # Здесь вызывается __init__
print(person.name) # Alice
Характеристики init:
- Вызывается один раз при создании экземпляра
- Инициализирует атрибуты объекта
- Не должен возвращать значение (кроме None)
- Позволяет установить начальное состояние
- Может валидировать входные параметры
dir — Список атрибутов
dir возвращает список доступных атрибутов и методов объекта. Вызывается встроенной функцией dir():
class Person:
class_attr = "class attribute"
def __init__(self, name):
self.name = name
self._private = "private"
def public_method(self):
pass
def __dir__(self):
return [name, class_attr, public_method]
person = Person("Bob")
print(dir(person)) # [name, class_attr, public_method]
Характеристики dir:
- Вызывается функцией dir() для интроспекции
- Возвращает список строк (имена атрибутов)
- Позволяет контролировать видимость атрибутов
- Полезна для скрытия внутренних деталей
- Влияет на автодополнение в IDE
Практическое сравнение
class DataProcessor:
def __init__(self, data):
# Выполняется ОДИН РАЗ при создании
self.data = data
self._cache = {}
self._processed = False
def __dir__(self):
# Выполняется при вызове dir()
# Скрываем внутренние атрибуты из публичного API
public_attrs = [data, process, get_result]
return sorted(public_attrs)
def process(self):
pass
def get_result(self):
pass
# Создание объекта вызывает __init__
processor = DataProcessor([1, 2, 3])
# Проверка доступных атрибутов вызывает __dir__
print(dir(processor))
# [data, get_result, process]
# Обратите внимание: _cache и _processed скрыты!
Когда они вызываются
| Метод | Когда вызывается | Зачем | Возвращает |
|---|---|---|---|
| init | При создании объекта | Инициализация состояния | None |
| dir | При вызове dir(obj) | Интроспекция | list[str] |
Взаимодействие с IDE и REPL
init — не видно IDE (IDE не может угадать, какие атрибуты будут созданы):
class User:
def __init__(self, username):
self.username = username
self.profile = None
# IDE НЕ будет подсказывать .username и .profile без аннотаций типов
dir и type hints вместе — дают лучшую IDE поддержку:
from typing import Any
class User:
username: str
profile: dict[str, Any] | None
def __init__(self, username: str):
self.username = username
self.profile = None
def __dir__(self) -> list[str]:
return [username, profile, get_profile]
# Теперь IDE знает о всех атрибутах!
Практическое применение dir
class APIClient:
def __init__(self, token):
self.token = token
self._session = None
self._retry_count = 3
def __dir__(self):
# Публичный API клиента
return [get, post, put, delete, token]
def get(self, url):
pass
def post(self, url, data):
pass
client = APIClient("secret-token")
print(dir(client))
# [delete, get, post, put, token]
# _session и _retry_count скрыты от пользователей
Резюме
- init — конструктор, инициализирует состояние объекта один раз
- dir — рефлексия, контролирует видимость атрибутов при интроспекции
- Они вызываются в разные времена и для разных целей
- init необходимо для работы объекта
- dir опционально, но улучшает DX и безопасность API