2016-07-04 60 views
3

我碰到下面的代碼來一邊唸叨元類here,雖然我不知道這種區別是特定於元類,我懷疑這是不是:爲什麼__new__和__init__在向超類踢球時表現出不同的表現?

class MetaBase(type): 
    def __new__(mcl, name, bases, nmspc): 
     print('MetaBase.__new__\n') 
     return super(MetaBase, mcl).__new__(mcl, name, bases, nmspc) 

    def __init__(cls, name, bases, nmspc): 
     print('MetaBase.__init__\n') 
     super(MetaBase, cls).__init__(name, bases, nmspc) 

注意,super().__init__()呼叫省略第一論據。我猜它是隱式傳遞的,因爲它正在調用一個由super()返回的任何類的方法。這就是我通常看到的構建這樣的調用的方式,雖然它們通常涉及到一個普通類上的self而不是元類上的cls/mcl。

儘管如此,super().__new__()調用通過mcl明確。我不明白爲什麼。簽名看起來和我一樣。

我很困惑。在每種情況下,super()是否會返回不同的東西?這裏發生了什麼事情,並且我應該在重寫其他魔術方法時期望被這個問題咬傷?

[編輯:有人建議這是this question的重複,它描述了它們的不同功能。而同樣差異中的一些例子顯示出在那裏,我看到或沒有說明爲什麼它的存在無論是獨特的__new__]

+4

'__new__'是一種靜態方法。 '__init__'是一個實例方法。 – spectras

+4

[Python使用\ _ \ _ new \ _ \ _和\ _ \ _ init \ _ \ _?]的可能重複(http://stackoverflow.com/questions/674304/pythons-use-of-new-and- init) – spectras

+0

關於編輯,'__new__'官方文檔的第一句話:「[__new __()是一個靜態方法(特殊的,所以你不需要聲明它)](https://docs.python.org/3 /參考/數據模型。html#object .__ new__)「 – spectras

回答

1

超().__新__()調用傳遞MCL明確,雖然。我不懂 爲什麼。簽名看起來和我一樣。

__new__方法是一個奇怪的地方,它是一個靜態方法,但它是特殊的,所以你不必聲明它是這樣的。作爲一個靜態方法意味着你必須顯式地傳入任何需要的變量(在這種情況下,元類)。

相比之下,__init__就像其他常規方法一樣。從實例中查找時,實例會自動作爲第一個參數傳入。無論您直接撥打cls.__init__(name, bases, nmspc)還是使用super()super(MetaBase, cls).__init__(name, bases, nmspc),都可以使用此功能。作爲第一個參數,他們都通過cls。這就是綁定方法對於普通類和元類的工作方式。不管是否使用super()

所以,一個奇怪的情況是__new__,因爲它是一個staticmethod,它根據定義沒有自動預先計劃行爲。

我應該期望在重寫其他魔術 方法時被此咬?

靜態方法很少見。在神奇的方法中,__new__是我能想到的唯一。所以,你應該安全:-)

相關問題