Python中, 仿照经典代码实现单例, 却出现了不是单例的的状态, 代码哪里出错了 ?
巴扎黑
巴扎黑 2017-04-18 10:24:53
0
1
598

实际现象

  • 期望实现单例, 保持某个属性全局唯一

预期现象

  • 仿照经典实现代码, 却出现了不是单例的情况

我要做什么

  • 实现scheduler全局唯一, 不派生过多的scheduler

重现步骤

  1. 拷贝代码

  2. 运行之

  3. 查看内存地址

相关代码

  • 仿照经典实现

from apscheduler.schedulers.background import BackgroundScheduler

class Borg(object):
    

    __shared_state = {}

    def __init__(self):
        self.__dict__ = Borg.__shared_state

        self.scheduler = BackgroundScheduler()
        
        
s1 = Borg().scheduler
s2 = Borg().scheduler

print s1, s2


# <apscheduler.schedulers.background.BackgroundScheduler object at 0x02623DF0> 
# <apscheduler.schedulers.background.BackgroundScheduler object at 0x02D801D0>
  • 我自己想的办法

from apscheduler.schedulers.background import BackgroundScheduler


class Borg(object):
    @classmethod
    def get_scheduler(cls):
        try:
            cls_scheduler = cls.scheduler
        except AttributeError as e:
            cls.scheduler = BackgroundScheduler()

            return cls.scheduler
        else:
            return cls_scheduler
        




bs1 = 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...

巴扎黑
巴扎黑

membalas semua(1)
洪涛

Contoh klasik ini tidak boleh dianggap sebagai singleton tulen, tetapi corak Brog dengan ciri tunggal.

Keajaibannya terletak pada penggunaan kamus atribut kelas Brog yang dikongsi oleh kelas __shared_state dan tika yang dibuat kemudian akan menimpa __dict__ kejadian sebelumnya.

s1 = Borg().scheduler
s2 = Borg().scheduler

Buat contoh s1 dan mulakan atribut scheduler pada masa yang sama Alamat pada masa ini ialah 0x02623DF0 Buat contoh lain s2, dan kemudian ubah suai atribut scheduler dan alamatnya 0x02D801D0. s1 dan s2 sebenarnya adalah dua kejadian berbeza, tetapi atribut mereka berkongsi atribut kelas, yang kelihatan seperti singleton.

Jika anda menukar kod ini, anda sepatutnya dapat melihat prosesnya dengan lebih jelas:

s1 = Borg()
print(s1.scheduler)
s2 = Borg()
print(s1.scheduler)
print(s2.scheduler)
print(s1.scheduler is s2.scheduler)
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan