Инициализатор против конструктора

Я слышал, что функция __init__ в python не является конструктором, это инициализатор, и на самом деле функция __new__ является конструктором, а разница в том, что функция __init__ вызывается после создания объекта, а функция __new__ вызывается раньше. Я прав? Вы можете лучше объяснить разницу и зачем нам нужны и __new__, и __init__?


person oridamari    schedule 01.03.2015    source источник
comment
Проверьте эту ссылку: stackoverflow.com/questions/ 674304 / pythons-use-of-new-and-init   -  person Vinkal    schedule 01.03.2015
comment
__init__ является прямым эквивалентом того, что другие объектно-ориентированные языки (особенно Java и C ++) обычно называют «конструктором». Насколько мне известно, эти языки на самом деле не имеют прямого эквивалента __new__. Но, вероятно, именно потому, что эквивалент «конструктора» на самом деле ничего не создает (как и «конструкторы» C ++ или Java), Python имеет тенденцию ссылаться на них как на имена реальных методов, а не на вызов либо конструктор.   -  person lvc    schedule 01.03.2015


Ответы (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 (хорошее это или плохое, однако, дело не в этом).

Хорошо это или плохо, но вы в основном можете контролировать процесс создания экземпляров и все, что это может означать в вашей конкретной ситуации.

person Eithos    schedule 01.03.2015

__init__ вызывается с уже созданным экземпляром объекта в качестве первого параметра (обычно называется self, но это просто имя параметра).

__new__ вместо этого вызывается с передачей класса в качестве первого параметра и, как ожидается, вернет экземпляр (который позже будет передан в __init__).

Это позволяет, например, __new__ возвращать уже существующий экземпляр для объектов на основе значений, которые являются неизменяемыми и для которых идентичность не должна играть роли.

person 6502    schedule 01.03.2015
comment
На какой класс вы ссылаетесь, когда говорите, что __new__ вызывается с передачей class в качестве первого параметра? - person HelloGoodbye; 22.08.2017
comment
@HelloGoodbye: класс создаваемого объекта. Это может быть тот же класс, в который вы помещаете __new__, или производный от него класс (в случае, если ни производная, ни другие базы, перечисленные перед этим классом, не определили __new__) - person 6502; 22.08.2017

Рассмотрение документации по настройке классов для получения дополнительных сведений.

В соответствии с этим эти методы используются следующим образом: __new__() для создания объекта и __init__() для его настройки.

И, как заметил 6502, __new__ является частным случаем статического метода и получает класс в качестве аргумента, а __init__ получает объект, созданный __new__

person Alexey Milogradov    schedule 01.03.2015