Подтвердить что ты не робот

Python: всегда используйте __new__ вместо __init__?

Я понимаю, как работают __init__ и __new__. Мне интересно, может ли что-нибудь __init__ сделать, что __new__ не может?

то есть. можно использовать __init__ для замены следующим шаблоном:

class MySubclass(object):
    def __new__(cls, *args, **kwargs):
        self = super(MySubclass, cls).__new__(cls, *args, **kwargs)
        // Do __init__ stuff here
        return self

Я спрашиваю, как бы я хотел сделать этот аспект Python OO лучше в моей голове.

4b9b3361

Ответ 1

Один возможный ответ от guido post (спасибо @fraca7):

Например, в модуле рассола __new__ используется для создания экземпляров при несериализации объектов. В этом случае экземпляры создаются, но метод __init__ не вызывается.

Любые другие подобные ответы?


Я принимаю этот ответ как "да" на свой вопрос:

Мне интересно, может ли что-нибудь __init__ сделать, что __new__ не может?

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

Ответ 2

Итак, класс класса обычно type, а при вызове Class() метод __call__() в классе Class обрабатывает это. Я считаю, что type.__call__() реализовано примерно так:

def __call__(cls, *args, **kwargs):
    # should do the same thing as type.__call__
    obj = cls.__new__(cls, *args, **kwargs)
    if isinstance(obj, cls):
        obj.__init__(*args, **kwargs)
    return obj

Прямой ответ на ваш вопрос - нет, вещи, которые __init__() может выполнять (изменить/ "инициализировать" указанный экземпляр), является подмножеством вещей, которые может __new__() (создавать или иным образом выбирать любой объект, который он хочет, сделать что-либо к тому объекту, который он хочет, прежде чем объект будет возвращен).

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

Ответ 3

Ну, ища __new__ vs __init__ на google показал мне этот.

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

EDIT: Чтобы ответить на ваш вопрос, вам не нужно переопределять __new__, если вы не подклассифицируете неизменяемые типы.