2017-02-21 71 views
0

我希望你做得很好。這個問題實際上是擺脫了對基類的引用。參考父母的班級方法,不用父母的班級名稱

基本上我想要在類級別而不是實例級別使用父級方法來收集子級類方法的所有方法。但是,我被告知基類名稱很長。

第一件作品,但由於長名稱真的很煩人。即使在乾淨的版本中,我也必須每次都做。

我保證人們不會在B中的任何一個孩子中定義另一種方法「吃」。我真的可以擺脫基類引用,以便我可以使用@eat嗎?

class IDontWantToDoThisButNameHasToBeThisLong(object): 

    a = [] 

    @classmethod 
    def eat(cls, func): 
    cls.a.append(func) 


class B(IDontWantToDoThisButNameHasToBeThisLong): 

    @IDontWantToDoThisButNameHasToBeThisLong.eat 
    def apple(self, x): 
    print x 

    IDontWantToDoThisButNameHasToBeThisLong.eat(lambda x: x+1) 

x = B() 

IDontWantToDoThisButNameHasToBeThisLong.a[0](x, 1) 

print IDontWantToDoThisButNameHasToBeThisLong.a[1](1) 

乾淨的版本:

class A(object): 

    a = [] 

    @classmethod 
    def eat(cls, func): 
    cls.a.append(func) 


class B(A): 

    @A.eat 
    def apple(self, x): 
    print x 

    A.eat(lambda x: x+1) 

x = B() 

A.a[0](x, 1) 
print A.a[1](1) 

真誠,

回答

0

IDontWantToDoThisButNameHasToBeThisLong實際上只是一個對象。在python中,大多數事物都是一個對象,所以我們可以將任何東西都分配給一個變量,包括一個類。

,你可以在這裏做的是一樣的東西下面

class IDontWantToDoThisButNameHasToBeThisLong(object): 

    a = [] 

    @classmethod 
    def eat(cls, func): 
     cls.a.append(func) 

A = IDontWantToDoThisButNameHasToBeThisLong 


class B(A): 

    @A.eat 
    def apple(self, x): 
     print x 

    A.eat(lambda x: x+1) 

x = B() 

IDontWantToDoThisButNameHasToBeThisLong.a[0](x, 1)   
A.a[0](x, 1) 

print IDontWantToDoThisButNameHasToBeThisLong.a[1](1) 
0

有你想做的事沒有完美的解決方案,但也有可能是不夠好幾個不同的方法。

首先從最簡單的,你可以給你的長類較短的名稱在子類中使用類方法之前:

class IDontWantToDoThisButNameHasToBeThisLong(object): 
    ... 

A = IDontWantToDoThisButNameHasToBeThisLong 

# later code can use A.whatever() 

另一種選擇是與長期移動裝飾出類的名稱,以便後面的代碼將其直接引用爲全局,而不是類方法。這就要求它稍微重新設計(這可能會打破東西,如果你曾經打算讓那裏是通過通過不同類別的所謂同一裝飾訪問多個不同的a列表):

class IDontWantToDoThisButNameHasToBeThisLong(object): 
    a = [] 

def eat(func): 
    IDontWantToDoThisButNameHasToBeThisLong.a.append(func) # only need to use the name once 
    return func # I suspect you want this too (a decorator should return a callable) 

# later code can use @eat as a decorator, without referring to the long class name 

這兩種的混合方法可能會離開現有的類方法的定義不變,但爲綁定的方法那是更容易獲得創建另一個全局名稱:

eat = IDontWantToDoThisButNameHasToBeThisLong.eat 

最後一個可能的方法是使用與元類票友編程,或者(如果你正在使用Python 3.6)__init_subclass__或類似的,以achi無需使用類方法作爲裝飾器,即可達到目標。我不會爲此包含代碼,因爲實現此目的的最佳方式可能取決於您的設計的更多細節,而不是您在示例中顯示的內容。