2 回答

TA貢獻(xiàn)1895條經(jīng)驗(yàn) 獲得超7個(gè)贊
好吧,我將停止查看您的代碼,而我的答案只是基于您的意見(jiàn):
我有一個(gè)基類(lèi),實(shí)際上我的應(yīng)用程序中的所有其他類(lèi)都可以擴(kuò)展(只是一些應(yīng)用程序內(nèi)功能的基本約定;也許應(yīng)該只是一個(gè)接口)。
這將ThesaurusBase在下面的代碼中
該基類(lèi)旨在容納一個(gè)詞庫(kù)類(lèi)的單例,該類(lèi)通過(guò)推斷一些同義詞(即{'yes':'yep','ok'})為用戶(hù)輸入提供一定的靈活性。
那將是ThesaurusSingleton,您可以使用更好的名稱(chēng)進(jìn)行調(diào)用并使其真正有用。
class ThesaurusBase():
def __init__(self, singleton=None):
self.singleton = singleton
def mymethod1(self):
raise NotImplementedError
def mymethod2(self):
raise NotImplementedError
class ThesaurusSingleton(ThesaurusBase):
def mymethod1(self):
return "meaw!"
class Thesaurus(TheraususBase):
def __init__(self, singleton=None):
TheraususBase.__init__(self, singleton)
def mymethod1(self):
return "quack!"
def mymethod2(self):
return "\\_o<"
現(xiàn)在,您可以按以下方式創(chuàng)建對(duì)象:
singleton = ThesaurusSingleton()
thesaurus = Thesaurus(singleton)
編輯:基本上,我在這里所做的是建立一個(gè)“基礎(chǔ)”類(lèi),該類(lèi)只是一個(gè)接口,該接口定義了其所有子類(lèi)的預(yù)期行為。該類(lèi)ThesaurusSingleton(我知道這是一個(gè)糟糕的名字)也正在實(shí)現(xiàn)該接口,因?yàn)槟f(shuō)過(guò)它也有,并且我不想討論您的設(shè)計(jì),所以您可能總是有奇怪的約束的充分理由。
最后,您是否真的需要在定義單例對(duì)象的類(lèi)中實(shí)例化您的單例?盡管可能有一些駭人聽(tīng)聞的方法,但是通常會(huì)有更好的設(shè)計(jì)來(lái)避免出現(xiàn)“駭人聽(tīng)聞”的部分。
我的想法是,無(wú)論您創(chuàng)建單身人士,都應(yīng)該明確地做到這一點(diǎn)。那就是“ Zen of python”:顯式比隱式好。為什么?因?yàn)檫@樣一來(lái),閱讀您的代碼的人(也許六個(gè)月后便會(huì)成為您)將能夠了解正在發(fā)生的事情以及編寫(xiě)該代碼時(shí)您在想什么。如果您嘗試使事情變得更隱式(例如使用復(fù)雜的元類(lèi)和怪異的自繼承),您可能會(huì)想知道這段代碼在不到三周的時(shí)間內(nèi)會(huì)做什么!
我并不是說(shuō)要避免這種選擇,而只是在沒(méi)有簡(jiǎn)單選擇的情況下才使用復(fù)雜的選擇!
根據(jù)您所說(shuō)的,我認(rèn)為我提供的解決方案可以作為起點(diǎn)。但是當(dāng)您專(zhuān)注于一些晦澀但不是非常有用的hacky東西而不是談?wù)撃脑O(shè)計(jì)時(shí),我不確定我的示例是否合適,并向您提示了設(shè)計(jì)。
edit2:還有另一種方法可以實(shí)現(xiàn)您想要的內(nèi)容(但請(qǐng)確保這確實(shí)是您想要的設(shè)計(jì))。您可能想使用將對(duì)類(lèi)本身(而不是實(shí)例)起作用的類(lèi)方法,從而使您能夠存儲(chǔ)自身的類(lèi)范圍的實(shí)例:
>>> class ThesaurusBase:
... @classmethod
... def initClassWide(cls):
... cls._shared = cls()
...
>>> class T(ThesaurusBase):
... def foo(self):
... print self._shared
...
>>> ThesaurusBase.initClassWide()
>>> t = T()
>>> t.foo()
<__main__.ThesaurusBase instance at 0x7ff299a7def0>
并且您可以initClassWide在聲明ThesaurusBase的模塊級(jí)別調(diào)用該方法,因此,每當(dāng)導(dǎo)入該模塊時(shí),該模塊都會(huì)加載單例(導(dǎo)入機(jī)制確保python模塊僅運(yùn)行一次)。

TA貢獻(xiàn)1848條經(jīng)驗(yàn) 獲得超6個(gè)贊
簡(jiǎn)短的答案是:
不要從超類(lèi)構(gòu)造函數(shù)實(shí)例化一個(gè)子類(lèi)的實(shí)例
更長(zhǎng)的答案:
如果您要這樣做的動(dòng)機(jī)是詞庫(kù)是一個(gè)單例事實(shí),那么最好使用類(lèi)(Thesaurus)中的靜態(tài)方法公開(kāi)該單例,并在需要該單例時(shí)調(diào)用此方法
添加回答
舉報(bào)