Python single instance mode

Python single instance###

#1 surroundings##

Python3.8.1

#2 What is a single instance##

The singleton mode is to ensure that there is only one instance of a class. When you want the entire system to have only one instance of a certain class, the singleton mode comes in handy

#3 Realize single instance method##

#3.1 Non-single instance###

classMyClass(object):

 def foo(self):return None

obj1 =MyClass()
obj2 =MyClass()print(obj1 is obj2)print(id(obj1))print(id(obj2))

#3.2 Use module###

classMyClass(object):

 def foo(self):return None

obj =MyClass()

use:

from singleton.mysingleton import obj

The python module is a natural singleton mode, because when the module is imported for the first time, it will generate a .pyc file. When it is imported for the second time, it will directly load the .pyc file instead of executing the module code again. We define related functions and data in a module, and we can get a singleton object

#3.3 Use decorator###

def singleton(cls):"""Decorator function"""

 class_instance ={} #Define a class that accepts instances

 def singleton_inner(*args,**kwargs):if cls not in class_instance: #Determine whether the class has been instantiated
   class_instance[cls]=cls(*args,**kwargs) #Not instantiated->Instantiate->Add the instantiated object to the dictionary

  return class_instance[cls] #Return instantiated object

 return singleton_inner 

@ singleton
classMyClass(object):

 def foo(self):return None

obj1 =MyClass()
obj2 =MyClass()print(obj1 is obj2)print(id(obj1))print(id(obj2))

Add a decorator before the class. The purpose of the decorator here is only one, that is, before the class is instantiated, first determine whether the class has been instantiated, if not, instantiate it, if it has been instantiated, the test returns the previous Instantiate object

#3.4 Use class###

classMyClass(object):

 def foo(self):return None

 @ classmethod
 def get_instance(cls,*args,**kwargs):"""Instantiate function"""if not hasattr(cls,'_instance'):
   cls._instance =cls(*args,**kwargs)return cls._instance

obj1 = MyClass.get_instance()
obj2 = MyClass.get_instance()print(obj1 is obj2)print(id(obj1))print(id(obj2))
obj3 =MyClass()print(id(obj3))

There are two disadvantages of implementing a single instance in this way:

  1. Only the sub-instantiated object like MyClass.get_instance() can achieve single instance, if it is instantiated in this way by MyClass(), single instance cannot be realized
  2. When multithreading, multiple instances are likely to appear, because when calling this class method get_instance(), if the init function consumes a long time during the instantiation process, then the instantiation of other threads will Think that you are the first to instantiate, this will lead to multiple instances

#3.5 Rewrite new method (recommended)

classMyClass(object):

 def foo(self):return None

 def __new__(cls,*args,**kwargs):if not hasattr(cls,'_instance'):
   cls._instance =super().__new__(cls)return cls._instance

obj1 =MyClass()
obj2 =MyClass()print(obj1 is obj2)print(id(obj1))print(id(obj2))

**The instantiation process of an object is to first execute the new method of the class. If we do not write, the new method of the object will be called by default to return an instantiated object, and then the init method will be called to initialize the object. , We can implement singleton according to this **

Recommended Posts

Python single instance mode
How does python enter interactive mode
Python requests module cookie instance analysis
Learn the basics of python interactive mode
Python generates arbitrary frequency sine wave mode