2016-09-23 5 views
1

Я знаю, что метод __new__ вызывается при попытке создать экземпляр класса до того, как будет вызван __init__.Импортирует вызов __new__ static method?

Но я случайно обнаружить, что импортировать модуль withou создать экземпляр будет также вызывать __new__

Предположим, у меня есть это:

a.py:

import abc 
class A(abc.ABCMeta): 
     def __new__(cls, name, bases, namespace): 
      print("ttt:", cls, name, bases, namespace) 
      retval = abc.ABCMeta.__new__(cls, name, bases, namespace) 
      return retval 


    class B(object): 
     __metaclass__ = A 

и

b.py

import a 

class C(B): 
    def a(): 
     pass 

Затем я выполняю python b.py, я вижу два ttt печатью __new__. Так что, когда делает нового точно называется, в этом случае, я никогда не создать любой экземпляр из трех классов я определенные

+0

Боковое примечание: '__new__' не является статическим методом. Это конструктор, который неявно ведет себя как метод класса (он получает класс как первый аргумент, а не экземпляр класса), но он не является статичным; static подразумевает, что это просто имена, помеченные классом, а не связанные с ним иным образом. – ShadowRanger

ответ

2

При использовании метакласса для определения класса, то метакласс «называется» неявным (который вызывает __new__, так как метакласс здесь является фактическим классом), см. Invoking the metaclass. Я не могу сказать, почему вы видите три отпечатка здесь (у вас есть только два класса, которые используют A как метакласс, прямо или косвенно через наследование), но это объясняет два из print.

+0

Извините за ошибку, у меня есть две отпечатки, одна для B, для C – demonguy

+0

@demonguy: Ну, вы точно не передали определение 'C' (' class (C): '- недопустимый синтаксис); если он также предполагает использование 'A' в качестве метакласса, что объясняет это. – ShadowRanger

+0

Да, вы правы, это «класс C (B):'. извините за typo.lol – demonguy