我有两个具有公共函数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
对名为A
和B
的两个变量执行相同的操作,这两个变量在结构上是等效的。我想将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
在此解决方案中,变量A
和B
已重命名为X
。但是,为了让我的代码更加自我解释,我想在特殊类中保留A
的特定名称(例如B
,X
)。
有办法做到这一点吗?
如果您可以建议更有意义和更具描述性的标题,请发表评论,以便它对社区更有价值。
编辑:如果变量A
,B
采用值为值传递的类型并且应该假设它们的值和类型,则解决方案也应该有效在程序执行期间可能会从课外改变。
答案 0 :(得分:2)
首先,需要注意的是:如果你的案例实际上要求你所描述的那种继承,那么变量名应该是相同的。在大多数情况下,为两个相关类中相同的属性赋予不同的名称不会使代码更自我解释 - 这使得更少自我解释。当它们真的相同时,它会使属性看起来不同,增加了复杂性和混淆的可能性。
但是,我可以想象一些你可能想要做这样的事情的情况 - 听起来有点像你想要为两种不同类型的对象定义一个公共接口。一种简单的方法是使用属性来定义别名;因此,在每个类中,您都有不同的属性(A
和B
),但您还要定义一个属性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