Note: The Python 2.7 is used.
A simple implementation
Copy codeThe Code is as follows:
Class Foo (object ):
_ Instance = None
Def _ init _ (self ):
Pass
@ Classmethod
Def getinstance (cls ):
If (cls. _ instance = None ):
Cls. _ instance = Foo ()
Return cls. _ instance
If _ name _ = '_ main __':
Foo1 = Foo. getinstance ()
Foo2 = Foo. getinstance ()
Print id (foo1)
Print id (foo2)
Print id (Foo ())
The first two results are the same (id (foo1) and id (foo2) values). The third result is different from the first two results. Here, the class method getinstance () is used to obtain the Singleton, but the class itself can also be instantiated. This method does not actually meet the requirements of the singleton mode. However, this method is also advantageous, and the code is simple. You just need to agree to call it like this. However, it is better to name the class as a singleton class, for example, Foo_singleton.
Another idea
Let's talk about the differences between init and new:
Copy codeThe Code is as follows:
Class Foo (object ):
_ Instance = None
Def _ init _ (self ):
Print 'init'
If _ name _ = '_ main __':
Foo = Foo ()
The running result is:
Copy codeThe Code is as follows:
Init
The following example:
Copy codeThe Code is as follows:
Class Foo (object ):
_ Instance = None
Def _ init _ (self ):
Print 'init'
Def _ new _ (cls, * args, ** kwargs ):
Print 'new'
If _ name _ = '_ main __':
Foo = Foo ()
The running result is:
Copy codeThe Code is as follows: new
New is a class method that is called when an object is created. The init method is called after the object is created. It initializes the instance of the current object and has no return value. If new is rewritten but init is not called in new or the instance is not returned, init does not work. Reference from http://docs.python.org/2/reference/datamodel.html#object.new
Copy codeThe Code is as follows:
If _ new _ () returns an instance of cls, then the new instance's _ init __() method will be invoked like _ init _ (self [,...]), where self is the new instance and the remaining arguments are the same as were passed to _ new __().
If _ new _ () does not return an instance of cls, then the new instance's _ init _ () method will not be invoked.
In this way:
Copy codeThe Code is as follows:
Class Foo (object ):
_ Instance = None
Def _ init _ (self ):
Print 'init'
Def _ new _ (cls, * args, ** kwargs ):
Print 'new'
If cls. _ instance = None:
Cls. _ instance = cls. _ new _ (cls, * args, ** kwargs)
Return cls. _ instance
If _ name _ = '_ main __':
Foo = Foo ()
The error is as follows:
Copy codeThe Code is as follows:
RuntimeError: maximum recursion depth exceeded in cmp
The same error also exists:
Copy codeThe Code is as follows:
Class Foo (object ):
_ Instance = None
Def _ init _ (self ):
If self. _ class _. _ instance = None:
Self. _ class _. _ instance = Foo ()
Print 'init'
If _ name _ = '_ main __':
Foo = Foo ()
What should we do?
Refer to the following:
Copy codeThe Code is as follows:
Class Foo (object ):
_ Instance = None
Def _ new _ (cls, * args, ** kwargs ):
Print 'hhhhhhhhh'
If not cls. _ instance:
Cls. _ instance = super (Foo, cls). _ new _ (cls, * args, ** kwargs)
Return cls. _ instance
Def hi (self ):
Print 'Hi, world'
Print 'Hi, letiany'
If _ name _ = '_ main __':
Foo1 = Foo ()
Foo2 = Foo ()
Print id (foo1)
Print id (foo2)
Print isinstance (foo1, object)
Print isinstance (foo1, Foo)
Foo1.hi ()
Running result:
Copy codeThe Code is as follows:
Hhhhhhhhh
Hhhhhhhhh
39578896
39578896
True
True
Hi, world
Hi, letian
So, let's first review what happened to super:
Copy codeThe Code is as follows:
>>> Print super. _ doc __
Super (type)-> unbound super object
Super (type, obj)-> bound super object; requires isinstance (obj, type)
Super (type, type2)-> bound super object; requires issubclass (type2, type)
Typical use to call a cooperative superclass method:
Class C (B ):
Def meth (self, arg ):
Super (C, self). meth (arg)
The line of code in the preceding Singleton mode code is certain:
Copy codeThe Code is as follows:
Cls. _ instance = super (Foo, cls). _ new _ (cls, * args, ** kwargs)
Super (Foo, cls) is the object, super (Foo, cls). new method uses the object's new method. Let's take a look at the functions of object. new:
Copy codeThe Code is as follows:
>>> Print object. _ new _. _ doc __
T. _ new _ (S,...)-> a new object with type S, a subtype of T
If it is an inheritance chain
Copy codeThe Code is as follows:
Class Fo (object ):
Def _ new _ (cls, * args, ** kwargs ):
Print 'Hi, I am fo'
Return super (Fo, cls). _ new _ (cls, * args, ** kwargs)
Class Foo (Fo ):
_ Instance = None
Def _ new _ (cls, * args, ** kwargs ):
If not cls. _ instance:
Print Foo is cls
Print issubclass (cls, Fo)
Print issubclass (cls, object)
Cls. _ instance = super (Foo, cls). _ new _ (cls, * args, ** kwargs)
Return cls. _ instance
Def hi (self ):
Print 'Hi, world'
If _ name _ = '_ main __':
Foo1 = Foo ()
Foo1.hi ()
Print isinstance (foo1, Foo)
Print isinstance (foo1, Fo)
Print isinstance (foo1, object)
The running result is as follows:
Copy codeThe Code is as follows:
True
True
True
Hi, I am Fo
Hi, world
True
True
True
If Fo is defined as follows, it also runs normally:
Copy codeThe Code is as follows:
Class Fo (object ):
Pass
However, if the definition is as follows:
Copy codeThe Code is as follows:
Class Fo (object ):
Def _ new _ (cls, * args, ** kwargs ):
Print 'Hi, I am fo'
The following error is reported during running:
Copy codeThe Code is as follows:
AttributeError: 'nonetype 'object has no attribute 'Hi'