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

Чем __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__ может быть использован для изменения процесса создания классов.

Как это работает?

  1. Создание объекта: Когда вы создаете объект, Python сначала вызывает __new__, чтобы создать новый экземпляр.
  2. Инициализация объекта: После создания объекта вызывается __init__, чтобы инициализировать его.

Тема: ООП
Стадия: Tech

🔒 Подпишись на бусти автора и стань Алигатором, чтобы получить полный доступ к функционалу сайта и отслеживать свой прогресс!

Твои заметки