__new__ не вызывается при создании объекта - PullRequest
0 голосов
/ 04 июля 2018

дело 1:

class Person:
    def __new__(cls, *args, **kwargs):
        print "called"
        return super(Person, cls).__new__(cls, *args, **kwargs)

p=Person()

дело 2:

class Person(object):
    def __new__(cls, *args, **kwargs):
        print "called"
        return super(Person, cls).__new__(cls, *args, **kwargs)

p=Person()

В первом случае метод __new__() не вызывается, но во втором случае он вызывается.

Если он не вызывается, то как создается Person объект?

Ответы [ 2 ]

0 голосов
/ 04 июля 2018

Я искал документацию и наконец нашел ее здесь: https://staging2.python.org/dev/peps/pep-0253/

Тип объекта имеет новый слот, tp_new, который может действовать как фабрика для экземпляры типа. Типы теперь можно вызывать, потому что tp_call слот установлен в PyType_Type (метатип); функция ищет слот tp_new вызываемого типа.

Чтобы добавить ответ @ devforfu, в старые времена __new__ не существовало. Он был добавлен с добавлением классов в новом стиле.

0 голосов
/ 04 июля 2018

Я думаю, это что-то связанное с классами нового и старого стиля в Python2:

Классы старого стиля на самом деле не имеют метода __new__, потому что для них __init__ конструктор, поэтому, в основном, если бы мы имели:

class A:

    def __new__(cls):
        print "A.__new__ is called"  # -> this is never called

A()

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

В Python3 поведение такое же, не имеет значения, наследуете ли вы явно от object или нет:

class Person1:
    def __new__(cls, *args, **kwargs):
        print("called")
        return super(Person1, cls).__new__(cls, *args, **kwargs)


class Person2(object):
    def __new__(cls, *args, **kwargs):
        print("called")
        return super(Person2, cls).__new__(cls, *args, **kwargs)


p1 = Person1()
p2 = Person2()

Они должны печатать "call" дважды при вызове из 3.x.

...