素材牛VIP会员
Python中, 仿照经典代码实现单例, 却出现了不是单例的的状态, 代码哪里出错了 ?
 sy***88  分类:Python  人气:1057  回帖:1  发布于6年前 收藏

实际现象

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

预期现象

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

我要做什么

  • 实现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...

 标签:python

讨论这个帖子(1)垃圾回帖将一律封号处理……

Lv2 入门
言***- 页面重构设计 6年前#1

经典例子这个不能算是纯单例,而是具有单例特性的Brog模式。

其魔法在于利用类Brog共享的类属性__shared_state的字典,后面创建的实例会覆盖前面实例的__dict__

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

创建一个实例s1,同时初始化属性scheduler,此时的地址是0x02623DF0,再创建一个实例s2,然后修改了属性scheduler,地址为0x02D801D0s1s2其实是两个不同实例,只不过他们的属性共用类属性,看起来就像单例的效果。

如果把代码改成这样,应该就能看得更清楚过程:

s1 = Borg()
print(s1.scheduler)
s2 = Borg()
print(s1.scheduler)
print(s2.scheduler)
print(s1.scheduler is s2.scheduler)
 文明上网,理性发言!   😉 阿里云幸运券,戳我领取