First, what is a singleton mode
Ensure that a class has only one instance and provides a global access point to access it
Second, the advantages
- Controlled access to a unique instance
- Simple interest is equivalent to a global variable, but prevents the namespace from being contaminated
Concepts similar to simple interest mode: Global variables, static variables (methods)
How can Why use singleton mode instead of global variables?
Answer, global variables may have namespace interference, if there is a duplicate name may be overwritten
Third, the use of the scene
- When a class has only one instance and the customer can access it from a well-known access point
- For example: Database link, socket creation link
Iv. four ways to implement single-case mode
# 1, Module import Form S1.pyclass Foo (object): Def test (self): print ("123") v = Foo () # V is an instance of Foo s2.pyfrom S1 import v as V1print (V1,id (v1)) #<s1. Foo object at 0x0000000002221710> 35788560from S1 import v as V2print (V1,id (v2)) #<s1. Foo object at 0x0000000002221710> 35788560# two memory address is the same # when the file is loaded, the first import will not reload again after the import.
# 2, based on the class implementation of the singleton mode # ====================== Singleton mode: cannot support multithreading case ===============class Singleton (object): Def __init__ (self): Import time Time.sleep (1) @classmethod def instance (CLS, *args, **kwargs): If not hasattr (Singleton, " _instance "): Singleton._instance = Singleton (*args, **kwargs) return singleton._instanceimport threading def task (arg): obj = Singleton.instance () print (obj) for i in range: T = Threading. Thread (Target=task,args=[i,]) T.start () # ==================== Singleton mode: Support Multithreading case ================, import timeimport Threadingclass Singleton (object): _instance_lock = Threading. Lock () def __init__ (self): time.sleep (1) @classmethod def instance (CLS, *args, **kwargs): If not ha Sattr (Singleton, "_instance"): With Singleton._instance_lock: #为了保证线程安全在内部加锁 if not hasattr (Si Ngleton, "_instance"): Singleton._instance = Singleton (*args, **kwargs) return Singleton._instAncedef Task (arg): obj = Singleton.instance () print (obj) for i in range: T = Threading. Thread (Target=task,args=[i,]) T.start () time.sleep () obj = Singleton.instance () print (obj) # using the first description, and later in singleton mode, obj = Singleton.instance () # example: # obj1 = Singleton.instance () # obj2 = Singleton.instance () # Print (OBJ1,OBJ2) # error Example # obj1 = Single ton () # obj2 = Singleton () # Print (OBJ1,OBJ2)
# 3, __new__-based implementation of Singleton mode # ============= single-threaded execution ===============import Threadingclass Singleton (object): _instance_lock = Threading. Lock () def __init__ (self): Pass def __new__ (CLS, *args, **kwargs): If not hasattr (Singleton, "_instanc E "): With Singleton._instance_lock:if not hasattr (Singleton," _instance "): # Class parentheses go back to execute the __new__ method, the __new__ method creates an instance of the class: Singleton () singleton._instance = object.__new__ (CLS) # inherits the object Class __new__ method, class to call method, description is function, to manually pass CLS return singleton._instance #obj1 #类加括号就会先去执行__new__方法, in execution __init__ method # Obj1 = Singleton () # obj2 = Singleton () # Print (OBJ1,OBJ2) # =========== multithreaded Execution Simple interest ============def task (arg): obj = Singleton () Print (obj) for i in range: T = Threading. Thread (Target=task,args=[i,]) T.start () # Use the first description, later in singleton mode, obj = Singleton () # example # obj1 = Singleton () # obj2 = Singleton () # p Rint (OBJ1,OBJ2)
# 4, based on Metaclass (meta-Class) Implementation of the Singleton mode "" "1. Objects are class-created, objects are created when the __init__ method of the class is executed automatically, the object () executes the __call__ method of the Class 2. Class is the type created, the class is created when the type of the __init__ method automatically executes, class () executes the __call__ method of type (__new__ method of Class, __init__ method of Class) # No. 0 Step: Execute type's __init__ method "Class is object of type" class Foo:def __init__ (sel f): Pass Def __call__ (self, *args, **kwargs): pass# 1th Step: Execute the type of the __call__ method # 1.1 Call the Foo class (is the type of the __new__ method, which is used to create an object. # 1.2 calls the __init__ method of the Foo class (the object of type), which is used to initialize the object. obj = Foo () # 2nd step: Execute Foo's __call__ method obj () "" "# =========== Class Execution Flow ================class singletontype (type): Def __init__ (s Elf,*args,**kwargs): Print (self) #会不会打印? #<class ' __main__. Foo ' > Super (singletontype,self) __init__ (*args,**kwargs) def __call__ (CLS, *args, **kwargs): #cls = Foo obj = cls.__new__ (CLS, *args, **kwargs) obj.__init__ (*args, **kwargs) return objclass Foo (Metaclass=singl Etontype): Def __init__ (self,name): self.name = name def __new__ (CLS, *args, **kwargs): Return object. __NEW__ (CLS,*args, **kwargs) ' 1, the object is created by the class, the __init__ method of the class is automatically executed when the object is created, the object () executes the class's __call__ Method 2, the class is type created, and the __init__ method of the type class is automatically executed when the class is created. Class () First executes the __call__ method of type (calling the __new__,__init__ method of the Class) Foo, which is created by the class Singletontype "obj = Foo (" Hiayan ") # ============ The third way to implement the singleton pattern =================import threadingclass singletontype (type): _instance_lock = Threading. Lock () def __call__ (CLS, *args, **kwargs): If not hasattr (CLS, "_instance"): With Singletontype._inst Ance_lock:if not Hasattr (CLS, "_instance"): Cls._instance = Super (SINGLETONTYPE,CLS). __ Call__ (*args, **kwargs) return Cls._instanceclass Foo (metaclass=singletontype): def __init__ (self,name): Self.name = Nameobj1 = foo (' name ') obj2 = foo (' name ') print (OBJ1,OBJ2)
Application of single-case model
# pool.pyimport Pymysqlimport threadingfrom dbutils.pooleddb import pooleddbclass Singletondbpool (object): _instance_l Ock = Threading. Lock () def __init__ (self): Self.pool = Pooleddb (creator=pymysql, # Using a linked database module maxconnect ions=6, # The maximum number of connections allowed for a connection pool, 0 and none means no limit on the number of connections mincached=2, # initialization, free links created at least in the link pool, 0 means not creating maxcached=5, # Link Pool The most idle links in 0 and none do not limit maxshared=3, # The number of links that are shared in the link pool, and 0 and none represent all sharing. PS: Useless, because Pymysql and mysqldb modules such as threadsafety are 1, all values regardless of set to how much, _maxcached forever is 0, so forever is all links are shared. Blocking=true, # If there are no available connections in the connection pool, wait is blocked. True, wait, False, do not wait and then error maxusage=none, # The number of times a link is reused, None means unrestricted setsession=[], # The list of commands executed before the session starts. such as: ["Set Datestyle to ...", "Set time zone ..."] ping=0, # Ping the MySQL server, check if the service is available. # for example: 0 = None = never, 1 = default = Whenever it is requested, 2 = When a cursor is created, 4 = When a query is executed, 7 = always host= ' 127.0.0.1 ', port=33User= ' root ', password= ' 123 ', database= ' pooldb ', charset= ' UTF8 ') Def __new__ (CLS, *args, **kwargs): If not hasattr (Singletondbpool, "_instance"): With Singletondbpool._ Instance_lock:if not hasattr (Singletondbpool, "_instance"): Singletondbpool._instance = Object.__new__ (CLS, *args, **kwargs) return singletondbpool._instance def Connect (self): return Self.poo L.connection ()
# App.pyfrom Pool import singletondbpooldef run (): pool = Singletondbpool () conn = Pool.connect () # xxxxxx< C3/>cursor = Conn.cursor () cursor.execute ("SELECT * from TD where id=%s", [5,]) result = Cursor.fetchall () # Get Data cursor.close () conn.close () if __name__ = = ' __main__ ': run ()
Four ways to develop "supplemental" singleton patterns in Python full stack