Python设计:面向对象

Python设计:面向对象,python,oop,inheritance,Python,Oop,Inheritance,我正试图按照以下思路做一些事情: 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 ):

我正试图按照以下思路做一些事情:

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)
这种设计的根本原因是A是一个数据容器(比如一个表),B和C是A上的一组操作。B和C都对相同的数据进行操作,但在概念上是可以对相同数据执行的一组不同的操作。我可以将B和C中的所有操作合并到A中,但我想在概念上创建分离。(例如,在一个表上,我可以执行不同的操作集,这些操作集可以分为微积分或三角测量。因此a:表,B:微积分,C:三角测量)

这让我想起了模型-视图-控制器范式,但有一点扭曲

我提出了以下解决方案:

  • B和C实现为概念上不同的类(a 视图/控制器),维护对和实例的引用 对那个实例进行操作
  • 因为B和C只是组合在一起 方法,创建具有在上运行的函数的模块 A的实例

  • 我不太喜欢这两种解决方案中的任何一种(2比1稍微好一点),但我不确定是否有更好/更干净/更具python风格的方法来解决这个问题。有什么指针吗?

    我是这样理解这个问题的:
    B
    C
    是使用
    A
    类型数据的函数集合。您要做的是对函数进行逻辑分组

    我建议做以下一项:

  • 将函数分成在
    A
    上运行的
    B
    C
    类——这是一种HAS-A关系。如果您需要的话,函数/方法可以是静态的
  • 将功能分为模块
    B
    C
    ,创建顶级功能定义

  • 我认为继承是解决这个问题的一个坏办法。我不认为存在IS-A关系。

    将状态移动到另一个类中,并将其实例作为A的属性:

    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()
    

    我不确定向我们展示打字错误的意义是什么,所以我在回答中忽略了它。1和2看起来非常地道。如果只想将几个函数组合在一起,就不要创建类。我同意,尽管我认为带有函数的模块比静态方法更像python。