что происходит, когда мы вызываем класс? - PullRequest
1 голос
/ 09 мая 2020

Кратко из python,

Где C - это класс, выражение x=C(23) эквивалентно:

x = C.__new__(C, 23) 
if isinstance(x, C): type(x).__init__(x, 23)

From Насколько я понимаю, object.__new__ создает новый неинициализированный экземпляр класса, который он получает в качестве своего первого аргумента.

Зачем нужен чек с isinstance(). Разве не очевидно, что __new__ вернет объект типа C.

Если это произойдет, что произойдет, если этот тест не пройден?

Поскольку classes - это callables, вызов __new__ выполняется в методе __call()__ класса

Я что-то упустил, пожалуйста, поясните мне

Ответы [ 2 ]

2 голосов
/ 09 мая 2020

Разве не очевидно, что __new__ вернет объект типа C.

Вовсе нет. Допустимо следующее:

>>> class C:
...   def __new__(cls):
...     return "not a C"
...   def __init__(self):
...     print("Never called")
...
>>> C()
'not a C'

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

Обратите внимание, что вы цитируете не совсем точно. x = C(32) эквивалентно на первом этапе x = type.__call__(C, 32). Это type.__call__ вызывает C.__new__, а затем решает, следует ли вызывать метод __init__ для возвращаемого значения.

Вы можете думать о type.__call__ как о чем-то вроде

def __call__(cls, *args, **kwargs):
    obj = cls.__new__(cls, *args, **kwargs)
    if isinstance(obj, cls):
        obj.__init__(*args, **kwargs)
    return obj

Применяя это к C, мы видим, что obj устанавливается в str значение 'not a C', а не как экземпляр C, так что 'not a C'.__init__ не вызывается перед возвратом строки.

0 голосов
/ 09 мая 2020

isinstance (a, b) используется для проверки того, является ли a экземпляром b. Не уверен, почему вы проверяете его после создания. Магические методы можно пересмотреть. Хотя в обычных случаях isinstance () необходим для проверки данных Dynami c.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...