想不到更好的问题标题。随意编辑。我有一个由许多类继承的基类(它可能有更多的子类)。对于每个类,我有一系列我需要执行后期初始化的操作。该序列被封装在功能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
调用基__init__
第一,它调用runme()
,这反过来将调用evaluate
。由于孩子过度乘坐evaluate
,执行的evaluate
孩子的定义,但作为self.ad1
还没有尚未被实例化,这将引发AttributeError
我可以从myBase删除self.runme()
,问题很可能会消失,但我可以进一步sublcass childA
为childAA
class childAA(childA):
def __init__(self,neg,op,value,ad1):
super(childAA,self).__init__(neg,op,value,ad1)
self.runme()
而且问题都可以重新显现。因为可以形成既childA
和childAA
的对象,我不能从childA的__init__
删除runme()
(和需要处理)
目前,作为一种解决方法,我不叫runme()
在__init__
,而不是从呼叫叫它初始化后的程序。
obja=childA(foo,bar,baz,ad1)
obja.runme()
一个更简单的方法是在孩子的__init__
结束调用super()
,但这并不出现是正确的
另一种方式是 - 告诉基类推迟调用邵仁枚的()到孩子班。这可能吗?在我的基地说,我做
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)
这段代码可以放在被调用第一在runme()
def preprocess(self):
self.internal_value = value
#Rest of the stuff
请看http://rhettinger.wordpress.com/2011/05/26/super-considered-super/;我认为如果'__init__'委托完成类的初始化,最后调用'super()'并不合逻辑。 – thkang 2013-04-18 07:02:35
你为什么认为“那不合适”?这正是您在这种情况下所需要的,这是最简单的解决方案。我没有看到任何理由使用非常复杂的代码,只是因为有人告诉你_easy_解决方案看起来不正确。 – 2013-04-18 07:37:34
@ running.t是的你是对的。其实我原来的解决方案并没有设想从子项中移除'runme()'调用。编辑了我的问题,包括我现在正在做的事情,因为两个人发布了相同的答案,然后将其删除 – RedBaron 2013-04-18 08:34:32