Example of a singleton pattern for Python design patterns

Source: Internet
Author: User
Tags print object
Note: Python 2.7 is used.

A simple implementation
Copy the Code code 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 of the output are the same (the ID (foo1) is the same as the value of the ID (FOO2), and the third result differs from the first two. Here the class Method getinstance () is used to obtain a singleton, but the class itself can also be instantiated, which in fact does not conform to the requirements of the singleton pattern. But this is also good, the code is simple, everyone agreed to this kind of call on the line. But it's better to name the class as well. This is a singleton class, such as Foo_singleton.

A different idea.

Let's talk about the difference between Init and NEW:
Copy the Code code as follows:


Class Foo (object):
__instance = None
def __init__ (self):
print ' init '
if __name__ = = ' __main__ ':
foo = foo ()


The operating result is:
Copy CodeThe code is as follows:


Init


And 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 operating 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, and some initialization is done on the instance of the current object, with no return value. If you rewrite new and do not call init in new or return an instance, then Init will not work. The following references are from Http://docs.python.org/2/reference/datamodel.html#object.new
Copy the Code code as follows:


If __new__ () returns an instance of CLS, then the new instance ' s __init__ () method would be a invoked like __init__ (self[,.. .]), where the new instance and the remaining arguments are the same as were passed to __new__ ().

If __new__ () does not return a instance of CLS, then the new instance ' s __init__ () method won't be invoked.


Do this:
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 the Code code as follows:


Runtimeerror:maximum recursion depth exceeded in CMP

And then there's the same error:
Copy the Code code 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 I do?

The following reference is made to http://stackoverflow.com/questions/31875/is-there-a-simple-elegant-way-to-define-singletons-in-python/31887#31887:
Copy the Code code 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, Letian '

if __name__ = = ' __main__ ':
Foo1 = Foo ()
Foo2 = Foo ()
Print ID (foo1)
Print ID (foo2)
Print Isinstance (Foo1, Object)
Print isinstance (foo1, Foo)
Foo1.hi ()


Operation Result:
Copy CodeThe code is as follows:


Hhhhhhhhh
Hhhhhhhhh
39578896
39578896
True
True
Hi, World
Hi, Letian


So, what happened, let's review super:

Copy the Code code 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)


You can be sure of this line of code in the above singleton pattern code:
Copy CodeThe code is as follows:


Cls.__instance = Super (Foo, CLS). __new__ (CLS, *args, **kwargs)


Super (foo, CLS) is Object,super (foo, CLS). The new method uses the new method of object. Let's take a look at the role of the Object.new method:
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 the Code code 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 results of the operation are as follows:
Copy CodeThe code is as follows:


True
True
True
Hi, I am Fo
Hi, World
True
True
True


If you define fo as follows, it will work as well:
Copy CodeThe code is as follows:


Class Fo (object):
Pass


However, if you define this:
Copy CodeThe code is as follows:


Class Fo (object):
Def __new__ (CLS, *args, **kwargs):
print ' Hi, I am Fo '


The Run Times error is as follows:
Copy CodeThe code is as follows:


Attributeerror: ' Nonetype ' object has no attribute ' Hi '
  • Contact Us

    The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

    If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.