I. Single-case model (Singleton)
The so-called singleton pattern, which is to ensure that only one object instance exists at any time. In many cases, only one object is needed throughout the system, and all information is obtained from this object, such as the system's configuration object, or the thread pool. These scenarios are ideal for using a single case pattern.
Summed up, that is, no matter how many times an object is initialized, the objects that are actually working are generated only once and are generated for the first time.
There are a number of ways to implement a single example pattern in Python, first to look at the first approach.
#!/usr/bin/python3
#-*-Coding:utf-8-*-
Class Singleton (object):
"""
Single row mode
"""
Class _a (object):
"""
The real work of the class, hidden externally.
"""
def __init__ (self):
Pass
def display (self):
"" Returns the ID of the current instance, which is the globally unique ""
Return ID (self)
# class variables, for storing instances of _a
_instance = None
def __init__ (self):
"" To determine whether the instance of _a has already been saved in the class variable, and if not, create one and then return ""
If Singleton._instance is None:
Singleton._instance = Singleton._a ()
def __getattr__ (self, attr):
Return GetAttr (self._instance, attr)
if __name__ = = "__main__":
# Create 2 instances
S1 = Singleton ()
S2 = Singleton ()
Print (ID (S1), S1.display ())
Print (ID (S2), S2.display ())
Using adorners
The adorner maintains a Dictionary object instances, caches all singleton classes, creates if the singleton does not exist, and returns the instance object directly.
Def Singleton (CLS):
instances = {}
def wrapper (*args, **kwargs):
If CLS not in instances:
INSTANCES[CLS] = CLS (*args, **kwargs)
return INSTANCES[CLS]
Return wrapper
@singleton
Class Foo (object):
Pass
Foo1 = Foo ()
Foo2 = Foo ()
Print Foo1 is Foo2 # True
Using the base class
__new__ is the way to actually create an instance object, so override the __new__ method of the base class to make sure that only one instance is generated when the object is created
Class Singleton (object):
Def __new__ (CLS, *args, **kwargs):
If not hasattr (CLS, ' _instance '):
Cls._instance = Super (Singleton, CLS). __new__ (CLS, *args, **kwargs)
Return cls._instance
Class Foo (Singleton):
Pass
Foo1 = Foo ()
Foo2 = Foo ()
Print Foo1 is Foo2 # True
Using the Meta class
The Meta Class (reference: A deep understanding of the Meta class in Python) is the class used to create the class object, the class object needs to call the __call__ method when it creates the instance object, so it is guaranteed to always create only one instance when the __call__ is invoked, and type is a meta class in Python.
Class Singleton (Type):
Def __call__ (CLS, *args, **kwargs):
If not hasattr (CLS, ' _instance '):
Cls._instance = Super (Singleton, CLS). __call__ (*args, **kwargs)
Return cls._instance
Class Foo (object):
__metaclass__ = Singleton
Foo1 = Foo ()
Foo2 = Foo ()
Print Foo1 is Foo2 # True
#!/usr/bin/python3 #-*-Coding:utf-8-*-Class Singleton (object): "" "single-row Mode" "Class _a (object):" "The real work of the class, hidden externally. "" "Def __init__ (self): Pass def display (self):" "" returns the ID of the current instance, is a globally unique "" Return ID (self) # class variable for storing _a instance _instance = Non E-def __init__ (self): "" "to determine whether the class variable has already saved an instance of _a, and if not, create one and then return" "if singleton._instance is none:singleton._instance = sin Gleton._a () def __getattr__ (self, attr): Return GetAttr (Self._instance, attr) If __name__ = "__main__": # create 2 instances S1 = Singleton () s2 = Singleton () print (ID (S1), S1.display ()) Print (ID (S2), S2.display ())
Output:
1917919737784 1917919737896
1917919738008 1917919737896
View Code
The above Single-column mode implementation uses the class variable singleton._instance to store the created instance and guarantees that only one instance is created. Because Python is a dynamic language, you can change the class definition at run time. In the code above, the instance of the class _a is first generated and stored in singleton._instance the first time the Singleton is initialized, and the actual working instance is obtained from singleton._instance each time the Singleton is initialized , thus implementing a single case pattern.
As you can see from the output, although you created two different instances (instance IDs are different), you get the same IDs when you access their properties. The code above is a good way to implement a single case pattern, but it's not flexible enough in real project development because the classes that actually work are built into the single instance class. We know that in Python the adorner is good, so can you implement a single instance class as an adorner? The answer is yes, the following implementation code.
#!/usr/bin/python3
#-*-Coding:utf-8-*-
Import Sqlite3
From flask Import Current_app
From flask import _app_ctx_stack as Stack
Class SQLite3 (object):
def __init__ (self, App=none):
Self.app = App
If app is not None:
Self.init_app (APP)
def Init_app (self, app):
"" "Typical flask Extension initialization method" "
App.config.setdefault (' Sqlite3_database ', ': Memory: ')
App.teardown_appcontext (Self.teardown)
def connect (self):
"" Connect to the SQLite database ""
Return Sqlite3.connect (current_app.config[' sqlite3_database ')
def teardown (self, exception):
"" Close SQLite link "" "
CTX = Stack.top
If Hasattr (CTX, ' sqlite3_db '):
Ctx.sqlite3_db.close ()
@property
def connection (self):
"""
Single case mode here: Use Flask._app_ctx_stack to store SQLite links,
Obtained by connection each time a database link is fetched
"""
CTX = Stack.top
If CTX is not None:
If not hasattr (CTX, ' sqlite3_db '):
ctx.sqlite3_db = Self.connect ()
Return ctx.sqlite3_db
In the above code, you can get a database connection by sqlite3.connection each time you use the database. Sqlite3.connection guarantees that a database connection occurs only once, in the same way that the singleton pattern was implemented before, except that the place where the instance was stored became flask._app_ctx_stack.
With the above code, you can see that an implementation of a singleton pattern only needs to find a variable to hold the created instance, and then every time you get the instance, check to see if the instance has been saved in the variable, and if not, create an instance and store it in the variable, and then get the instance from that variable. In singleton mode, only one instance is created.