【问题标题】:Python design: OOPPython设计:OOP
【发布时间】:2011-10-17 14:58:38
【问题描述】:

我正在尝试按照以下方式做一些事情:

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:Table, B: Calculus, C:Trignometry)

这让我想起了稍微扭曲的模型-视图-控制器范式。

我想出了以下解决方案:

  1. B 和 C 被实现为概念上不同的类(a View/Controller) 维护对 A 实例的引用和 对该实例进行操作。
  2. 由于 B 和 C 只是组合在一起 A 上的方法,创建具有在 A 上运行的函数的模块 A 的实例。

我不太喜欢这些解决方案中的任何一个(2 比 1 略好),但是我不确定是否有更好/更清洁/更 Python 的方法来解决这个问题。有什么指点吗?

【问题讨论】:

  • 我不确定向我们展示 TypeError 的意义何在,所以我在回答中忽略了它。
  • 1 & 2 看起来非常地道。如果您只想将几个函数组合在一起,请不要创建类。

标签: python oop inheritance


【解决方案1】:

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

我建议执行以下操作之一:

  1. 将函数分成BC 类,它们在A 上运行——这是一种HAS-A 关系。如果您需要,函数/方法可以是静态的
  2. 将函数分成BC模块,创建顶级函数定义

我认为继承对于这个问题来说是一个不好的解决方案。我不认为存在 IS-A 关系。

【讨论】:

  • 同意,虽然我认为带有函数的模块比静态方法更 Pythonic。
【解决方案2】:

在附加类中移动状态并使其实例成为 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()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-18
    • 2011-10-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多