2013-06-27 32 views
1

從另一個類借用實例方法的實現非常簡單,但是如何使用類方法實現呢?從另一個類(Python 3)借用類方法

class A: 
    def im(self): 
    print(self.__class__.__name__) 

    @classmethod 
    def cm(cls): 
    print(cls.__name__) 

class B: 
    im = A.im 
    cm = A.cm # line X 
    classmethod(cm) 

B().im() # B - OK 
B.cm() # A - not what I want 

我也試着更改行X爲cm = A.cm.__func__,造成TypeError: cm() missing 1 required positional argument: 'cls'

回答

3

您需要:

class B: 
    im = A.im 
    cm = classmethod(A.cm.__func__) 

當您訪問A.cm,產生的類方法已經 「知道」 它屬於如果你想重新包裝一個不同的類,你需要用__func__來提取底層函數,然後用classmethod重新包裝它。

此外,在您的示例中,行classmethod(cm)什麼都不做,因爲您不會將結果分配給任何東西。

+0

啊!所以我改變X線的方式是正確的 - 只有我也應該將下面一行改爲'cm = classmethod(cm)'。 –

+0

@ Heny'Pi'James:是的,這與我的解決方案具有相同的效果。 – BrenBarn

4

當您訪問A.cm時,將調用classmethod對象作爲descriptor,這表示它已經綁定到A類。再次解開它:

class B: 
    cm = classmethod(A.cm.__func__) 

.__func__屬性,您可以訪問原來的功能,這樣你就可以用新的classmethod呼叫重新包起來。

或者,使用A.__dict__映射獲得實際的類方法本身,繞過描述稱:

class B: 
    cm = A.__dict__['cm'] 
+0

這種替代方式看起來很有趣,但也有點骯髒。 –

+0

這是防止描述符協議踢入的唯一方法;它主要是爲了說明。 –

相關問題