2011-10-17 130 views
4

我試圖做的東西沿着這些路線:Python的設計:面向對象

class A: 

    def __init__(self, x=None, y=None): 
     self.x = x 
     self.y = y 

class B(A): 

    def do_something_in_Bs_context(self): 
     print "In B" 

class C(A): 

    def do_something_in_Cs_context(self): 
     print "In C" 


a = A(1,2) 
b = B.do_something_in_Bs_context(a) 
c = C.do_something_in_Cs_context(a) 

正如所預期的這個代碼將產生此錯誤:

TypeError: unbound method do_something_in_Bs_context() must be called with B instance as first argument (got A instance instead) 

這個設計的根本原因是,是數據的容器(比如一個表),B和C是A上的一組操作.B和C都運行在相同的數據上,但在概念上是一組不同的操作,可以在同一個數據上執行。我可以將A和B內的所有操作分開,但是我想在概念上創建分離。 (作爲一個例子,在一張桌子上,我可以執行不同的操作集合,這些操作集合成微積分或者三角函數,所以A:表格B:微積分C:紅外光譜)

這讓我想起Model-視圖 - 控制器範例略有扭曲。

我想出了以下解決方案:

  1. B和C是這樣實現的概念上不同的類(一個 視圖/控制器),其保持到A的實例的引用和 在該實例上進行操作。
  2. 由於關於A B和C只組一起 方法,創建具有功能上A.

的 實例進行操作的模塊,我不喜歡這兩種解決方案的多(2略好於1 ),但是我不確定是否有更好的/更清潔/更pythonic的方式來解決這個問題。任何指針?

+0

我不知道我們展示點的類型錯誤是,所以我忽略了它在我的答案。 –

+0

1&2似乎完全習慣用法。如果您只想將幾個功能組合在一起,請不要創建課程。 – delnan

回答

6

以下是我對問題的理解:BC是使用類型爲A的數據的函數的集合。你想要做的是將邏輯上的功能分組。

我建議做以下之一:

  1. 的功能分成上A的操作類BC - 這是一個HAS-A關係。該函數/方法可以是靜態的,如果這就是你所需要的
  2. 功能分成模塊BC,創建頂級函數定義

我想繼承將是一個壞的解決這個問題。我認爲不存在IS-A關係。在一個附加的類

+3

同意,但我認爲具有函數的模塊比靜態方法更具Pythonic。 –

1

移動狀態和作出的屬性它的一個實例:

class State(object): 
    def __init__(self, x=None, y=None): 
     self.x = x 
     self.y = y 

class A(object): 
    def __init__(self, state=None): 
     self.state = state 

class B(A): 
    def __init__(self, state=None): 
     super(B, self).__init__(state) 

    def do_something_in_Bs_context(self): 
     print self.state.x 

class C(A): 
    def __init__(self, state=None): 
     super(C, self).__init__(state) 

    def do_something_in_Cs_context(self): 
     print self.state.y 

s = State(1, 2) 
b = B(s) 
c = C(s) 
b.do_something_in_Bs_context() 
c.do_something_in_Cs_context()