Какова роль метода __new__ в Python и чем он отличается от __init__

Ответ

Магический метод __new__ — это конструктор класса, который отвечает за создание и возврат нового экземпляра. Он вызывается до __init__.

Основное отличие от __init__:

  • __new__(cls, ...): Создает объект. Это статический метод (хоть и без декоратора), который принимает класс cls в качестве первого аргумента. Он должен вернуть экземпляр класса.
  • __init__(self, ...): Инициализирует уже созданный объект (self). Ничего не возвращает (None). Его задача — настроить начальное состояние объекта.

Когда используется __new__:

Чаще всего __new__ переопределяют для реализации специфических паттернов или при работе с неизменяемыми (immutable) типами.

Пример: Паттерн Singleton

Цель — гарантировать, что у класса есть только один экземпляр.

class Singleton:
    _instance = None

    def __new__(cls, *args, **kwargs):
        # Если экземпляр еще не создан
        if cls._instance is None:
            # Создаем его с помощью родительского __new__
            print("Создание нового экземпляра...")
            cls._instance = super().__new__(cls)
        else:
            print("Возврат существующего экземпляра...")
        # Возвращаем единственный экземпляр
        return cls._instance

    def __init__(self):
        # Инициализация будет вызываться каждый раз, но на одном и том же объекте
        print("Инициализация объекта...")

a = Singleton()
# > Создание нового экземпляра...
# > Инициализация объекта...
b = Singleton()
# > Возврат существующего экземпляра...
# > Инициализация объекта...

print(f"a is b: {a is b}") # Вывод: a is b: True