__init__
: Это самый распространенный способ. Можно добавить свою логику инициализации экземпляра класса.__new__
: Метод __new__
отвечает за создание экземпляра класса, а __init__
- за его инициализацию. Можно переопределить __new__
для контроля над процессом создания объекта.Чтобы изменить поведение конструктора класса в Python, можно использовать несколько подходов:
__init__
: Это самый распространенный способ. Вы определяете метод __init__
в вашем классе и добавляете или изменяете логику, необходимую для инициализации экземпляра класса. Важно помнить о вызове super().__init__(...)
(если класс наследуется от другого класса), чтобы инициализировать атрибуты родительского класса, если это необходимо. Если вы не вызываете super().__init__(...)
, то вы полностью заменяете инициализацию родительского класса.
class MyClass:
def __init__(self, arg1, arg2="default"):
self.attribute1 = arg1
self.attribute2 = arg2
print("Конструктор MyClass вызван")
class MySubClass(MyClass):
def __init__(self, arg1, arg3):
super().__init__(arg1) # Вызов конструктора родительского класса
self.attribute3 = arg3
print("Конструктор MySubClass вызван")
__new__
: Метод __new__
отвечает за создание экземпляра класса, а __init__
- за его инициализацию. __new__
получает класс (cls) как первый аргумент и должен возвращать экземпляр этого класса. Если вы хотите контролировать процесс создания объекта (например, реализовать Singleton), __new__
– подходящий вариант. __init__
вызывается *после* __new__
только в том случае, если __new__
возвращает экземпляр класса (или его подкласса). Если __new__
возвращает что-то другое, __init__
не вызывается.
class Singleton:
_instance = None
def __new__(cls, *args, **kwargs):
if cls._instance is None:
cls._instance = super().__new__(cls)
print("Создан новый экземпляр")
else:
print("Возвращен существующий экземпляр")
return cls._instance
def __init__(self, value):
# Инициализация экземпляра, если он создан впервые
if not hasattr(self, 'value'): # Проверка, инициализирован ли экземпляр ранее
self.value = value
class MyMeta(type):
def __call__(cls, *args, **kwargs):
print("Перед созданием экземпляра")
instance = super().__call__(*args, **kwargs)
print("После создания экземпляра")
return instance
class MyClass(metaclass=MyMeta):
def __init__(self, value):
self.value = value
print("Инициализация MyClass")
def add_greeting(cls):
class Wrapper:
def __init__(self, *args, **kwargs):
self.instance = cls(*args, **kwargs)
self.instance.greeting = "Hello!"
def __getattr__(self, name):
return getattr(self.instance, name)
return Wrapper
@add_greeting
class Greeter:
def __init__(self, name):
self.name = name
greeter = Greeter("Alice")
print(greeter.name) # Выведет: Alice
print(greeter.greeting) # Выведет: Hello!
Выбор конкретного подхода зависит от требуемой степени контроля над процессом создания и инициализации объектов, а также от сложности решаемой задачи.