In Python, a single instance is implemented by imitating the classic code, but there is a state that is not a single instance. What is wrong with the code?

  python

Actual phenomenon

  • It is expected to implement a single instance and keep a certain attribute globally unique.

Expected phenomenon

  • Following the classic implementation code, there is a situation that is not a single case.

what you want me to do?

  • Implements scheduler globally unique and does not derive too many schedulers.

Reproduction step

  1. Copy code

  2. Run it

  3. View memory address

Related codes

  • Imitate the classic implementation

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>
  • I think of my own way

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>

Context environment

Classic example This is not a pure case, but has the characteristics of a single case.BrogMode.

The magic lies in the use of classesBrogShared class properties__shared_stateThe dictionary of the previous instance will be overwritten by the instance created later__dict__.

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

Create an instances1, initializing the property at the same timeschedulerThe address at this time is0x02623DF0And create another instances2, and then modified the propertyscheduler, address0x02D801D0.s1Ands2In fact, there are two different instances, but their attributes share class attributes, which looks like the effect of a single instance.

If you change the code to this, you should be able to see the process more clearly:

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