亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Python2.7:超級__init__創建其自己的子類的實例時發生無限循環

Python2.7:超級__init__創建其自己的子類的實例時發生無限循環

收到一只叮咚 2021-03-12 15:10:13
我覺得這一定是一個愚蠢的問題-此處不談。因此,我很樂意回答“這是向后的,請不要這樣做,請嘗試以下方法:[正確的方法] ”。我正在使用Python 2.7.5。問題的一般形式這會導致無限循環,除非Thesaurus(應用程序范圍內的單例)不調用Baseclass.__init__()class Baseclass():    def __init__(self):        thes = Thesaurus()        #do stuffclass Thesaurus(Baseclass):    def __init__(self):        Baseclass.__init__(self)        #do stuff我的具體情況我有一個基類,實際上我的應用程序中的所有其他類都可以擴展(只是一些應用程序內功能的基本約定;也許應該只是一個接口)。此基類旨在容納一個Thesaurus類的單例,該類通過推斷一些同義詞(即{'yes':'yep', 'ok'})為用戶輸入提供一定的靈活性。但是由于子類調用超類的__init__(),而后者又創建了另一個子類,因此隨之而來。不能稱呼超類的__init__()工作效果很好,但我擔心這只是一個幸運的巧合,而且我的Thesaurus類最終可能會被修改為需要其父類__init__()。
查看完整描述

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模塊僅運行一次)。


查看完整回答
反對 回復 2021-03-31
?
慕勒3428872

TA貢獻1848條經驗 獲得超6個贊

簡短的答案是:

不要從超類構造函數實例化一個子類的實例

更長的答案:

如果您要這樣做的動機是詞庫是一個單例事實,那么最好使用類(Thesaurus)中的靜態方法公開該單例,并在需要該單例時調用此方法


查看完整回答
反對 回復 2021-03-31
  • 2 回答
  • 0 關注
  • 224 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號