The single-case pattern is very much written, but the regular type of single-case mode is this, the various codes may be slightly different, but the core is to figure out the properties of class attribute instances, it is easy to write, the principle is exactly the same.
As follows:
Source:
classA (object):def __new__(CLS, *args, * *Kwargs):if notHasattr (CLS,'__inst'): Print('Execute New') obj= Super (A, CLS).__new__(CLS) setattr (CLS),'__inst', obj)returnobjElse: returnAl1.__dict__['__inst'] def __init__(self, x):Print('Execute init') self.x=xif __name__=='__main__': A1= A (1) Print('a1.x', a1.x) A2= A (2) Print('a2.x', a2.x)Print('a1.x', a1.x) A3= A.__new__(A)#a3.__init__ (3) # a3 = A (3) is actually called the new and Init methods, where the mask calls Init Print('a3.x', a3.x)Print(ID (A1), ID (A2), ID (A3))
Three objects were instantiated, and the results of the execution can be guessed:
It can be found that a new is executed once, but the Init was executed two times, which is run under the new class, and Python3 defaults to the new class, regardless of whether or not it inherits object.
If it is python2 and does not inherit object, it is actually only printed to execute the init once. So this is another difference between the py2 and the py3, the difference between the classic class and the new class is very much, and the reflection method of the new class is somewhat different from the classic class. But the general article only says that the difference between the new class and the classic class is only the breadth first and depth first, misleading.
3, the ultimate goal is to make Python3 instances also do not have more execution of the INIT, (because although the singleton mode can be controlled to be all instances of the class to point to the same object, but sometimes the singleton mode initialization is to establish an IO connection or resource pool, so that each execution of initialization waste some time)
Two methods, one is to add a class attribute to do flags, add if judgment in the Init method
The second is, do not use a = a (XXXX), but use a = a.__new__ (a), because A = a (xxxx), is actually a = a.__new__ (a), and a.__init__ (XXX)
4, There is also a way to use the adorner, if you follow this method will not perform multiple init
#Coding=utf8 fromFunctoolsImportWrapsdefSingleton (CLS):PrintCLS Instances={} @wraps (CLS)defgetinstance (*args, * *kw):ifCls not inchInstances:instances[cls]= CLS (*args, * *kw)returnInstances[cls]returnGetinstance@singletonclassMyClass (object): a= 1M1=MyClass () M2=MyClass ()PrintM1 isM2
The Python singleton mode is controlled to initialize only once, and the generic Python singleton pattern differs from the new class and the classic class.