2016-09-23 62 views
1

我知道在調用__init__之前嘗試創建類的實例時會調用__new__方法。進口調用__new__靜態方法嗎?

但我偶然發現,導入模塊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__'不是一個靜態方法。它是構造函數,它隱含地表現爲類方法(它接收類作爲其第一個參數,而不是類的實例),但它不是靜態的;靜態意味着它僅僅是由這個類命名空間,而不是與之相關聯。 – ShadowRanger

回答

2

當您使用元類來定義一個類三大類的任何實例,元類是「被稱爲」隱性(其中調用__new__,因爲這裏的元類是實際的類),請參閱Invoking the metaclass。我不能說爲什麼你在這裏看到三個打印(你只有兩個類使用A作爲元類,直接或間接通過繼承),但這解釋了兩個print s。

+0

對不起,我有兩個打印,一個用於B,用於C – demonguy

+0

@demonguy:那麼,你沒有準確地傳達'C'的定義('class(C):'是無效的語法)。如果它也涉及使用'A'作爲元類,那就可以解釋它。 – ShadowRanger

+0

是的,你說得對,它是C類(B):'。對於typo.lol感到抱歉 – demonguy