Python中, 仿照經典代碼實現單例, 卻出現了不是單例的的狀態, 代碼哪里出錯了 ?
問題描述
實際現象期望實現單例, 保持某個屬性全局唯一
預期現象仿照經典實現代碼, 卻出現了不是單例的情況
我要做什么實現scheduler全局唯一, 不派生過多的scheduler
重現步驟拷貝代碼
運行之
查看內存地址
相關代碼仿照經典實現
from apscheduler.schedulers.background import BackgroundSchedulerclass Borg(object):__shared_state = {} def __init__(self):self.__dict__ = Borg.__shared_stateself.scheduler = BackgroundScheduler()s1 = Borg().schedulers2 = Borg().schedulerprint s1, s2# <apscheduler.schedulers.background.BackgroundScheduler object at 0x02623DF0> # <apscheduler.schedulers.background.BackgroundScheduler object at 0x02D801D0>
我自己想的辦法
from apscheduler.schedulers.background import BackgroundSchedulerclass Borg(object): @classmethod def get_scheduler(cls):try: cls_scheduler = cls.schedulerexcept AttributeError as e: cls.scheduler = BackgroundScheduler() return cls.schedulerelse: return cls_schedulerbs1 = Borg.get_scheduler()bs2 = Borg.get_scheduler()bs3 = Borg.get_scheduler()print bs1, bs2, bs3# <apscheduler.schedulers.background.BackgroundScheduler object at 0x02752D70> # <apscheduler.schedulers.background.BackgroundScheduler object at 0x02752D70> # <apscheduler.schedulers.background.BackgroundScheduler object at 0x02752D70>上下文環境
產品版本: Python 2.7 APScheduler最新
操作系統: Linux
Github鏈接, 經典實現: https://github.com/faif/pytho...
問題解答
回答1:經典例子這個不能算是純單例,而是具有單例特性的Brog模式。
其魔法在于利用類Brog共享的類屬性__shared_state的字典,后面創建的實例會覆蓋前面實例的__dict__。
s1 = Borg().schedulers2 = Borg().scheduler
創建一個實例s1,同時初始化屬性scheduler,此時的地址是0x02623DF0,再創建一個實例s2,然后修改了屬性scheduler,地址為0x02D801D0。s1和s2其實是兩個不同實例,只不過他們的屬性共用類屬性,看起來就像單例的效果。
如果把代碼改成這樣,應該就能看得更清楚過程:
s1 = Borg()print(s1.scheduler)s2 = Borg()print(s1.scheduler)print(s2.scheduler)print(s1.scheduler is s2.scheduler)
相關文章:
1. md5 - python中如何校驗本地目錄和遠程目錄?2. Python中range(1,1)返回什么?3. python pymysql 執行比較時間的sql語句,在mysql中可以順了執行,但是在python中執行為何報錯?4. Python中如何將爬取到的數據循環存入到csv文件中?5. Python中怎么實現1:n:1的數據結構?6. 反射 - Python中,有控制函數流程和上下文的辦法么?7. python中class里面的self是什么意思?8. 請問python中為什么我用for循環對嵌套列表進行賦值時,都是以i的最終值來計算的?9. linux - Python中aysncio的事件循環是屬于線程還是進程?10. python中split如何優先使用
