2016-03-14 28 views
2

我的情況是,我可以訪問兩個很好地結合在一起的類。廣泛地修改他們的代碼可能是不可能的,但也許可以實現小的改變。但是,我想要對這兩個類進行一些小的擴展。這看起來像是一個子類化工作,從每個類派生和添加功能。但我碰到一個問題,因爲一個基類調用另一個,而不是我的派生類。Python:在一個基類的方法中初始化一個新的派生類

假設我在模塊'base_classes.py'中有兩個類A和B. B類有一個方法可以創建A類的一個實例並使用它,例如

'base_classes.py'

class A(): 
    def __init__(self): 
     print('Class A being called') 

class B(): 
    def __init__(self): 
     self.do_thing() 
    def do_thing(self): 
     self.myA = A() # Here class A is explicitly named 

所以我想繼承這兩個和擴展它們。我這樣做,在一個單獨的模塊:

「extensions.py」

import base_classes 

class DerivedA(base_classes.A): 
    def __init__(self): 
     super().__init__() 
     print('Class DerivedA being called') 

class DerivedB(base_classes.B): 
    pass 

db = DerivedB() 

正如所預期的輸出僅僅是

Class A being called 

但我怎麼能防止我乙的子類作出方法do_thing(self)中A的基類的實例,而是生成DerivedA的實例?

簡單的方法是覆蓋DerivedB中的do_thing(self),以便它顯式調用DerivedA例如

class DerivedB(base_classes.B): 
    def do_thing(self): 
     self.myA = DerivedA() # Here class DerivedA is explicitly named 

這是罰款,這個小例子,但如果do_thing(self)是幾百行代碼,並含有A型的許多對象?如果B中的大多數方法包含一些A對象會怎麼樣?基本上每個方法都必須覆蓋幾乎完全相同的副本,因此首先從B派生出來沒有意義。這就是我的問題,我認爲必須有一個聰明的Python方法來解決這個問題。理想情況下,沒有完全重寫原始類。

任何想法?

+0

調用它,你需要以某種方式信息'DeriveB'必須調用'DeriveA'。它可以在名稱上或者以'B .__ init __(DerivedA)'爲參數。這裏有很多方法。 – Cyrbil

回答

0

您可以更改B類的do_thing方法,並通過一類參數:

class B(): 
    def __init__(self): 
     self.do_thing() 
    def do_thing(self, klass=A): 
     self.myA = klass() 

然後derivedB do_thing方法可以與DerivedA

class DerivedB(base_classes.B): 
    def do_thing(self, klass=DerivedA): 
     return super(DerivedB, self).do_thing(klass) 
+1

或者信息可能在類屬性'self .__ class __。do_thing_class' – tripleee

+0

@tripleee right – loutre

+0

好的。我希望能夠徹底改變基礎班。但是這似乎很小。謝謝 – ddossett

相關問題