2011-01-19 38 views
2

我需要來自第三方模塊m的類X的某些功能。我可以直接使用m.X,但我可能需要將m.X替換爲未來的另一個類n.Y(例如,如果我發現更好的實現)。python:圍繞第三方類寫封裝

我想避免在這種情況下更改其他代碼。

現在,我希望m.X的完整接口(包括初始化)通過不變。我寫了一包裹材料W的m.X如下:

class W(m.X): 
    def __init__(self, *args): 
     super().__init__(*args) 

今後,如有需要,我打算重寫上面爲:

class W(n.Y): 
    def __init__(self, *args): 
     super().__init__(*args) 
    # override instance methods of n.Y that don't share the semantics with m.X 
    # for example, in case f1 is hard to replicate in n.Y: 
    # def f1(self, *args): 
    #  print("this method is no longer available") 
    #  raise MyDeprecatedMethod() 
    # for example, in case f2 needs to be recalculated 
    # def f2(self, *args): 
      # do the calculations required to keep W.f2 unchanged 

是我目前的包裝器m.X接受嗎?它是否有問題,或與n.Y的計劃包裝?

+0

看起來不錯(至少,這是我的方式) – 2011-01-19 01:57:59

+0

你真的需要多少包裝?如果唯一的問題是屏蔽代碼的其他命名,那麼只需`W = m.X`就足夠了,不是嗎? – 2011-01-19 04:38:40

回答

2

最簡單的方法是寫:

W = m.X 

實際上一切在Python是第一類對象 - 包括類型。一類是從任何其他變量幾乎難以區分,例如:雖然看起來即W是它的實際名稱

def W(*args, **kwargs): 
    return m.X(*args, **kwargs) 

可以實例m.X的一個實例。 (請注意,用這種方法isinstance將無法​​正常工作 - 它做工精細與第一例子)

在某些情況下,使用分配可能無法很好地與IDE玩。在這種情況下:

class W(m.X): pass 

也將產生同樣的結果,但在的W該情況下,增加的開銷是m.X唯一實例,因爲W是一個子類:使用W=m.X; W(args)將創建m.X一個實例。

3

你可以簡單地使用

class W(m.X): 
    pass 

在默認情況下繼承m.X.__init__()

0

這將取決於MX和紐約多麼的不同是你使用他們的方法,但它可能是那樣簡單

try: 
    import n.Y as foo 
except ImportError: 
    import m.X as foo 

class W(foo): 
    pass 

所以你的代碼會自動反映新的模塊,最大限度地減少潛在的變化,你需要在整個代碼庫中完成。