两个类具有结构相同的方法,但有一个不同的命名变量

时间:2014-01-31 14:28:38

标签: python class oop refactoring

我有两个具有公共函数f的类,如下所示:

class ClassA(object):

    def f(self, var):
        self.A = g(var, self.A)

    # specific code for ClassA, also changing self.A

class ClassB(object):

    def f(self, var):
        self.B = g(var, self.B)

    # specific code for ClassB, also changing self.B

在这两个类中,f对名为AB的两个变量执行相同的操作,这两个变量在结构上是等效的。我想将f放入抽象类中以避免代码重复。一种方法是

class ClassX(object):

    def f(self, var):
        self.X = g(var, self.X)

class ClassA(ClassX):

    # specific code for ClassA, also changing self.X

class ClassB(ClassX):

    # specific code for ClassB, also changing self.X

在此解决方案中,变量AB已重命名为X。但是,为了让我的代码更加自我解释,我想在特殊类中保留A的特定名称(例如BX)。

有办法做到这一点吗?

如果您可以建议更有意义和更具描述性的标题,请发表评论,以便它对社区更有价值。

编辑:如果变量AB采用值为值传递的类型并且应该假设它们的值和类型,则解决方案也应该有效在程序执行期间可能会从课外改变。

2 个答案:

答案 0 :(得分:2)

首先,需要注意的是:如果你的案例实际上要求你所描述的那种继承,那么变量名应该是相同的。在大多数情况下,为两个相关类中相同的属性赋予不同的名称不会使代码更自我解释 - 这使得更少自我解释。当它们真的相同时,它会使属性看起来不同,增加了复杂性和混淆的可能性。

但是,我可以想象一些你可能想要做这样的事情的情况 - 听起来有点像你想要为两种不同类型的对象定义一个公共接口。一种简单的方法是使用属性来定义别名;因此,在每个类中,您都有不同的属性(AB),但您还要定义一个属性X,在任何一种情况下都可以访问相应的属性。所以在ClassA中,你会在类定义中做类似的事情:

@property
def X(self):
    return self.A
@x.setter
def X(self, value):
    self.A = value
@x.deleter
def X(self):
    del self.A

ClassB

@property
def X(self):
    return self.B
@x.setter
def X(self, value):
    self.B = value
@x.deleter
def X(self):
    del self.B

然后,您可以定义一个只适用于X的公共函数,子类可以继承,以适当的方式覆盖属性X

很少值得额外的间接层。大多数情况下,如果有两个类共享方法的充分理由,那么它们也应该共享方法更改的属性,名称和所有。

答案 1 :(得分:1)

如果你想要做的只是别名实例属性,你可以使用property

class A(object):

    def f(self, var):
        self.x = g(var, self.x)

    @property
    def x(self):

        return getattr(self, self.x_alias)

    @x.setter
    def x(self, val):

        setattr(self, self.x_alias, val)

class AA(A):

    x_alias = 'aval'

    def __init__(self, aval):

        self.aval = aval

class AB(A):

    x_alias = 'bval'

    def __init__(self, bval):

        self.bval = bval