Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI28 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Разница между new и init
Это два ключевых метода в жизненном цикле создания объекта в Python. Они работают на разных уровнях.
new (Создание объекта)
Предназначение: создает новый экземпляр класса
- Вызывается первым
- Статический метод (принимает cls, не self)
- Отвечает за выделение памяти под объект
- Должен вернуть новый экземпляр класса
- Если new не вернул экземпляр класса, init не будет вызван
class MyClass:
def __new__(cls, *args, **kwargs):
print("__new__ вызван - создание объекта")
instance = super().__new__(cls) # Создаём объект
return instance # Возвращаем новый объект
def __init__(self, value):
print("__init__ вызван - инициализация")
self.value = value
obj = MyClass(42)
# __new__ вызван - создание объекта
# __init__ вызван - инициализация
init (Инициализация объекта)
Предназначение: инициализирует атрибуты созданного объекта
- Вызывается вторым
- Обычный метод (принимает self)
- Отвечает за установку начальных значений атрибутов
- Возвращает None
- Работает с уже созданным объектом
class User:
def __init__(self, name, age):
print("__init__ вызван")
self.name = name
self.age = age
user = User("Иван", 30)
# Объект уже существует, __init__ просто заполняет атрибуты
print(user.name) # Иван
Последовательность вызовов
MyClass(args, kwargs)
|
v
__new__(cls, args, kwargs) <- Создание объекта
|
v
(возвращает instance)
|
v
__init__(instance, args, kwargs) <- Инициализация объекта
|
v
instance готов к использованию
Практический пример
class Singleton:
_instance = None
def __new__(cls):
# Контролируем создание - возвращаем один экземпляр
if cls._instance is None:
print("Создаю новый экземпляр Singleton")
cls._instance = super().__new__(cls)
else:
print("Возвращаю существующий экземпляр")
return cls._instance
def __init__(self):
print("__init__ вызван")
self.created_at = None
# Первый вызов
s1 = Singleton()
# Создаю новый экземпляр Singleton
# __init__ вызван
# Второй вызов
s2 = Singleton()
# Возвращаю существующий экземпляр
# __init__ вызван
print(s1 is s2) # True - это один и тот же объект
Когда нужен new?
1. Singleton паттерн - контроль количества экземпляров
class Database:
_instance = None
def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = super().__new__(cls)
return cls._instance
2. Иммутабельные объекты - кэширование и переиспользование
class ImmutablePoint:
_cache = {}
def __new__(cls, x, y):
key = (x, y)
if key not in cls._cache:
instance = super().__new__(cls)
cls._cache[key] = instance
return cls._cache[key]
def __init__(self, x, y):
self.x = x
self.y = y
p1 = ImmutablePoint(1, 2)
p2 = ImmutablePoint(1, 2)
print(p1 is p2) # True - тот же объект из кэша
3. Работа с встроенными типами - создание подклассов
class MyList(list):
def __new__(cls, iterable):
# list не вызывается __init__ как обычный класс
# используем __new__ для инициализации
return super().__new__(cls, iterable)
ml = MyList([1, 2, 3])
print(ml) # [1, 2, 3]
Важные моменты
| Аспект | new | init |
|---|---|---|
| Вызов | Первый | Второй |
| Тип метода | @staticmethod | Обычный |
| Первый параметр | cls | self |
| Возвращает | Экземпляр класса | None |
| Назначение | Создание памяти | Инициализация |
| Обязателен | Нет (есть по умолчанию) | Нет (есть по умолчанию) |
Типичная ошибка
# Неправильно - забыли вернуть instance
class Wrong:
def __new__(cls):
super().__new__(cls) # Не вернули!
def __init__(self):
self.value = 42
obj = Wrong() # Возвращает None!
print(obj.value) # AttributeError!
# Правильно
class Right:
def __new__(cls):
return super().__new__(cls) # Вернули instance
def __init__(self):
self.value = 42
obj = Right()
print(obj.value) # 42
Вывод: используй new только когда нужно контролировать создание объекта (singleton, кэширование). В 99% случаев достаточно init.