Я слышал, что функция __init__
в python не является конструктором, это инициализатор, и на самом деле функция __new__
является конструктором, а разница в том, что функция __init__
вызывается после создания объекта, а функция __new__
вызывается раньше. Я прав? Вы можете лучше объяснить разницу и зачем нам нужны и __new__
, и __init__
?
Инициализатор против конструктора
Ответы (3)
По сути, __new__
отвечает за создание экземпляра (таким образом, может быть правильным сказать , что это конструктор, как вы заметили), в то время как __init__
действительно является способом инициализации состояния в экземпляре. . Например, рассмотрите это:
class A(object):
def __new__(cls):
return object.__new__(cls)
def __init__(self):
self.instance_method()
def instance_method(self):
print 'success!'
newA = A()
Обратите внимание, что __init__
получает аргумент self
, а __new__
получает класс (cls
). Поскольку self
является ссылкой на экземпляр, это должно с очевидностью сказать вам, что экземпляр уже создан к моменту вызова __init__
, поскольку он передается экземпляру. Также возможно вызывать методы экземпляра именно потому, что экземпляр уже был создан.
Что касается вашего второго вопроса, по моему опыту редко возникает необходимость использовать __new__
. Безусловно, бывают ситуации, в которых __new__
могут использоваться более продвинутые методы, но это редко. Один из печально известных примеров, когда у людей может возникнуть соблазн использовать __new__
, - это создание класса Singleton (хорошее это или плохое, однако, дело не в этом).
Хорошо это или плохо, но вы в основном можете контролировать процесс создания экземпляров и все, что это может означать в вашей конкретной ситуации.
__init__
вызывается с уже созданным экземпляром объекта в качестве первого параметра (обычно называется self
, но это просто имя параметра).
__new__
вместо этого вызывается с передачей класса в качестве первого параметра и, как ожидается, вернет экземпляр (который позже будет передан в __init__
).
Это позволяет, например, __new__
возвращать уже существующий экземпляр для объектов на основе значений, которые являются неизменяемыми и для которых идентичность не должна играть роли.
__new__
вызывается с передачей class в качестве первого параметра?
- person HelloGoodbye; 22.08.2017
__new__
, или производный от него класс (в случае, если ни производная, ни другие базы, перечисленные перед этим классом, не определили __new__
)
- person 6502; 22.08.2017
Рассмотрение документации по настройке классов для получения дополнительных сведений.
В соответствии с этим эти методы используются следующим образом: __new__()
для создания объекта и __init__()
для его настройки.
И, как заметил 6502, __new__
является частным случаем статического метода и получает класс в качестве аргумента, а __init__
получает объект, созданный __new__
__init__
является прямым эквивалентом того, что другие объектно-ориентированные языки (особенно Java и C ++) обычно называют «конструктором». Насколько мне известно, эти языки на самом деле не имеют прямого эквивалента__new__
. Но, вероятно, именно потому, что эквивалент «конструктора» на самом деле ничего не создает (как и «конструкторы» C ++ или Java), Python имеет тенденцию ссылаться на них как на имена реальных методов, а не на вызов либо конструктор. - person lvc   schedule 01.03.2015