В Python создание объекта происходит в два этапа, за которые отвечают два разных магических метода: __new__
и __init__
. Рассмотрим их различия и последовательность выполнения.
Пример:
class Example:
def __new__(cls, *args, **kwargs):
print("__new__ выполняется")
instance = super().__new__(cls) # Создаем экземпляр
return instance
__new__
Пример:
def __init__(self, value):
print("__init__ выполняется")
self.value = value
При вызове Example()
происходит:
__new__
:
__init__
:
Пример полного цикла:
obj = Example(10)
# Вывод:
# __new__ выполняется
# __init__ выполняется
Характеристика | __new__ | __init__ |
---|---|---|
Назначение | Создание объекта | Инициализация объекта |
Аргумент | cls (класс) | self (экземпляр) |
Возвращаемое значение | Новый экземпляр | None |
Вызов | Первым | Вторым |
Использование | Реже, для особых случаев | Часто, в большинстве классов |
class Immutable:
def __new__(cls, value):
instance = super().__new__(cls)
instance._value = value
return instance
def __setattr__(self, name, value):
raise AttributeError("Неизменяемый объект")
class Singleton:
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
class PositiveNumber:
def __new__(cls, value):
if value > 0:
return super().__new__(cls)
return None
__init__
(99% кода)class CustomTuple(tuple):
def __new__(cls, a, b):
return super().__new__(cls, (a, b))
def __init__(self, a, b):
self.a = a # Не сработает для tuple!
# Для неизменяемых типов вся работа в __new__
__new__
- конструктор, создает объект (вызывается первым)__init__
- инициализатор, настраивает объект (вызывается вторым)__new__
→ (создание объекта) → __init__
__init__
__new__
нужен для:
__init__
, для неизменяемых - в __new__
Понимание различий между этими методами важно для продвинутой работы с классами в Python и реализации специфического поведения при создании объектов.