想不到更好的問題標題。隨意編輯。我有一個由許多類繼承的基類(它可能有更多的子類)。對於每個類,我有一系列我需要執行後期初始化的操作。該序列被封裝在功能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