想不出更好的问题标题。随意编辑。我有一个基类,它被许多类继承(而这些类又可能有更多的子类)。对于每个类,我都有一系列需要执行初始化后的操作。该序列被封装在一个函数中,该函数runme()
执行一系列对象方法调用
class myBase(object):
def __init__(self,neg,op,value):
self.neg = neg
self.op = op
self.value = value
#Process
self.runme()
def runme(self):
self.preprocess()
self.evaluate()
self.postprocess()
def preprocess(self):
pass
def evaluate(self):
pass
def postprocess(self):
pass
子类必须接受与基类相同的属性(以及任何附加属性)。它们都将覆盖三个函数-preprocess
和evaluate
postprocess
class childA(myBase):
def __init__(self,neg,op,value,ad1):
super(childA,self).__init__(neg,op,value)
self.ad1 = ad1
#Must call runme() here again??
runme()
def evaluate():
#Something using self.ad1
blah = self.ad1+self.value
在我看来,它会产生一个问题——首先childA
调用 base __init__
,然后调用runme()
,然后调用evaluate
. 由于 child over-rides evaluate
,child 的定义evaluate
被执行,但由于self.ad1
还没有被实例化,这会抛出一个AttributeError
我可以self.runme()
从 myBase 中删除,问题可能会消失,但我可以进一步childA
转入childAA
class childAA(childA):
def __init__(self,neg,op,value,ad1):
super(childAA,self).__init__(neg,op,value,ad1)
self.runme()
问题可能会再次出现。我无法runme()
从 childA中删除,__init__
因为两者的对象都可以形成(并且需要处理childA
)childAA
目前,作为一种解决方法,我不调用runme()
,__init__
而是在初始化后从调用程序中调用它。
obja=childA(foo,bar,baz,ad1)
obja.runme()
super()
一个更简单的替代方法是在 child's 的末尾调用,但这似乎__init__
不正确
另一种方法是 - 告诉基类将 runme() 的调用推迟到子类。这可能吗?在 myBase 中说,我愿意
def __init__(self,neg,op,value):
self.neg = neg
self.op = op
self.value = value
#Process
if some_condition which checks if this is being called by a derived class:
self.runme()
如果这些是解决它的最佳方法?或者,这是一个常见问题吗?还有哪些其他建议的解决方案?
编辑
发布(并删除)了两个答案,这同意最好的方法似乎是runme()
在基类中留下电话,然后super()
在孩子的末尾调用__init__
class myBase(object):
def __init__(self,neg,op,value):
self.neg = neg
self.op = op
self.value = value
#Process
self.runme()
class childA(myBase):
def __init__(self,neg,op,value,ad1):
self.ad1 = ad1
super(childA,self).__init__(neg,op,value)
如果您需要依赖于现有值的值,
class childA(myBase):
def __init__(self,neg,op,value,ad1):
self.ad1 = ad1
self.internal_value = self.value #Not yet initialized!!
super(childA,self).__init__(neg,op,value)
这段代码可以放在第一个preprocess()
被调用的函数或其他函数中runme()
def preprocess(self):
self.internal_value = value
#Rest of the stuff