2011-10-17 98 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()