Как в Python отменить или изменить создание экземпляра класса в методе __new__

«Как в Python отменить или изменить создание экземпляра класса в методе __new__» — вопрос из категории ООП, который задают на 10% собеседований Python Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Да, метод __new__ в Python позволяет контролировать процесс создания экземпляра. В отличие от __init__, который инициализирует уже созданный объект, __new__ его создает и возвращает.

Чтобы отменить или изменить создание, __new__ может вернуть:

  • Существующий экземпляр: Это основной механизм для реализации паттерна Singleton.
  • Экземпляр другого класса: Можно перенаправить создание на другой класс.
  • None: Технически возможно, но это приведет к ошибке TypeError, так как последующий вызов __init__ получит None вместо ожидаемого экземпляра.

Важно: Метод __init__ вызывается только в том случае, если __new__ возвращает экземпляр того же класса (cls).

Пример (Singleton):

class Singleton:
    _instance = None

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

        # Всегда возвращаем единственный экземпляр
        return cls._instance

    def __init__(self):
        # Этот код будет выполняться при каждом вызове Singleton(),
        # даже если возвращается старый экземпляр.
        print("Вызов __init__")

s1 = Singleton()
# Вывод:
# Создание нового экземпляра
# Вызов __init__

s2 = Singleton()
# Вывод:
# Возврат существующего экземпляра
# Вызов __init__

print(s1 is s2) # True