Ответ
Метод __new__ — это статический метод класса, который отвечает за создание и возврат нового экземпляра класса. Он вызывается перед методом __init__.
В свою очередь, __init__ — это метод экземпляра, который отвечает за инициализацию уже созданного объекта (например, за установку его атрибутов). Он ничего не возвращает.
Ключевые отличия:
| Характеристика | __new__(cls, ...) |
__init__(self, ...) |
|---|---|---|
| Назначение | Создание экземпляра | Инициализация экземпляра |
| Тип метода | Статический (первый аргумент — класс cls) |
Экземпляра (первый аргумент — экземпляр self) |
| Возвращаемое значение | Должен вернуть экземпляр класса | Не должен ничего возвращать (None) |
| Порядок вызова | Вызывается первым | Вызывается вторым, после __new__ |
Основные случаи использования __new__:
- Реализация паттерна Singleton, когда нужно контролировать процесс создания и гарантировать наличие только одного экземпляра класса.
- Наследование от неизменяемых (immutable) типов, таких как
str,intилиtuple, поскольку их значения нужно задать на этапе создания.
Пример (Singleton):
class Singleton:
_instance = None
def __new__(cls, *args, **kwargs):
# Если экземпляр еще не создан
if cls._instance is None:
# Создаем новый экземпляр, вызывая __new__ родительского класса
cls._instance = super().__new__(cls)
# Возвращаем существующий или только что созданный экземпляр
return cls._instance
# Проверка
a = Singleton()
b = Singleton()
print(f"a is b: {a is b}") # Вывод: a is b: True