2 回答

TA貢獻1895條經驗 獲得超7個贊
好吧,我將停止查看您的代碼,而我的答案只是基于您的意見:
我有一個基類,實際上我的應用程序中的所有其他類都可以擴展(只是一些應用程序內功能的基本約定;也許應該只是一個接口)。
這將ThesaurusBase在下面的代碼中
該基類旨在容納一個詞庫類的單例,該類通過推斷一些同義詞(即{'yes':'yep','ok'})為用戶輸入提供一定的靈活性。
那將是ThesaurusSingleton,您可以使用更好的名稱進行調用并使其真正有用。
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<"
現在,您可以按以下方式創建對象:
singleton = ThesaurusSingleton()
thesaurus = Thesaurus(singleton)
編輯:基本上,我在這里所做的是建立一個“基礎”類,該類只是一個接口,該接口定義了其所有子類的預期行為。該類ThesaurusSingleton(我知道這是一個糟糕的名字)也正在實現該接口,因為您說過它也有,并且我不想討論您的設計,所以您可能總是有奇怪的約束的充分理由。
最后,您是否真的需要在定義單例對象的類中實例化您的單例?盡管可能有一些駭人聽聞的方法,但是通常會有更好的設計來避免出現“駭人聽聞”的部分。
我的想法是,無論您創建單身人士,都應該明確地做到這一點。那就是“ Zen of python”:顯式比隱式好。為什么?因為這樣一來,閱讀您的代碼的人(也許六個月后便會成為您)將能夠了解正在發生的事情以及編寫該代碼時您在想什么。如果您嘗試使事情變得更隱式(例如使用復雜的元類和怪異的自繼承),您可能會想知道這段代碼在不到三周的時間內會做什么!
我并不是說要避免這種選擇,而只是在沒有簡單選擇的情況下才使用復雜的選擇!
根據您所說的,我認為我提供的解決方案可以作為起點。但是當您專注于一些晦澀但不是非常有用的hacky東西而不是談論您的設計時,我不確定我的示例是否合適,并向您提示了設計。
edit2:還有另一種方法可以實現您想要的內容(但請確保這確實是您想要的設計)。您可能想使用將對類本身(而不是實例)起作用的類方法,從而使您能夠存儲自身的類范圍的實例:
>>> 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的模塊級別調用該方法,因此,每當導入該模塊時,該模塊都會加載單例(導入機制確保python模塊僅運行一次)。

TA貢獻1848條經驗 獲得超6個贊
簡短的答案是:
不要從超類構造函數實例化一個子類的實例
更長的答案:
如果您要這樣做的動機是詞庫是一個單例事實,那么最好使用類(Thesaurus)中的靜態方法公開該單例,并在需要該單例時調用此方法
添加回答
舉報