Чем __new__ отличается от __init__ ?
1️⃣ Как кратко ответить
__new__ — это метод, который отвечает за создание нового экземпляра класса. Он вызывается перед __init__ и возвращает сам экземпляр. __init__ — это метод инициализации, который настраивает уже созданный экземпляр. __new__ используется редко, в основном при наследовании от неизменяемых типов, таких как tuple или str.
2️⃣ Подробное объяснение темы
В Python, когда мы создаем новый объект класса, происходит два основных этапа: создание объекта и его инициализация. Эти этапы управляются методами __new__ и __init__ соответственно.
Что такое __new__?
__new__ — это специальный метод, который отвечает за создание нового экземпляра класса. Он вызывается перед __init__ и его задача — вернуть новый объект класса. Это статический метод, который принимает в качестве первого аргумента сам класс, а затем любые дополнительные аргументы, которые были переданы при создании объекта.
class MyClass:
def __new__(cls, *args, **kwargs):
print("Creating instance")
instance = super().__new__(cls)
return instance
def __init__(self, value):
print("Initializing instance")
self.value = value
obj = MyClass(10)
В этом примере сначала вызывается __new__, который создает объект, а затем __init__, который инициализирует его.
Что такое __init__?
__init__ — это метод инициализации, который настраивает уже созданный объект. Он вызывается сразу после __new__ и принимает в качестве первого аргумента сам объект (обычно self), а также любые дополнительные аргументы, которые были переданы при создании объекта.
class MyClass:
def __init__(self, value):
print("Initializing instance")
self.value = value
obj = MyClass(10)
Здесь __init__ используется для установки начального состояния объекта.
Зачем нужен __new__?
__new__ используется редко, но он необходим, когда вы работаете с неизменяемыми типами данных, такими как tuple, str, или int. Например, если вы хотите создать подкласс от tuple и изменить способ его создания, вам нужно переопределить __new__.
class MyTuple(tuple):
def __new__(cls, iterable):
print("Creating MyTuple instance")
return super().__new__(cls, iterable)
my_tuple = MyTuple([1, 2, 3])
Где применяется?
- Неизменяемые типы: Используется для создания экземпляров классов, которые наследуются от неизменяемых типов.
- Синглтоны: Можно использовать для контроля создания экземпляров, например, в паттерне Singleton.
- Метаклассы: В метаклассах
__new__может быть использован для изменения процесса создания классов.
Как это работает?
- Создание объекта: Когда вы создаете объект, Python сначала вызывает
__new__, чтобы создать новый экземпляр. - Инициализация объекта: После создания объекта вызывается
__init__, чтобы инициализировать его.
🔒 Подпишись на бусти автора и стань Алигатором, чтобы получить полный доступ к функционалу сайта и отслеживать свой прогресс!
Подписаться