As a material for learning GoF design patterns, the book "Introduction to Design Patterns Learned in the Augmented and Revised Java Language" seems to be helpful. However, since the examples taken up are based on JAVA, I tried the same practice in Python to deepen my understanding.
The Singleton pattern (singleton pattern) is one of the design patterns in an object-oriented computer program. Defined by the GoF (Gang of Four; 4 gangs). The Singleton pattern is a design pattern that guarantees that only one instance of the class will be created. Used to implement mechanisms that must be absolutely unified across the application, such as locale and look and feel (The above is quoted from Wikipedia)
Let's define a class that can only create one instance.
Main.py
class Singleton(object):
def __new__(cls, *args, **kargs):
if not hasattr(cls, "_instance"):
cls._instance = super(Singleton, cls).__new__(cls)
return cls._instance
class Myclass(Singleton):
def __init__(self, input):
self.input = input
if __name__ == '__main__':
one = Myclass(1)
print("one.input={0}".format(one.input))
two = Myclass(2)
print("one.input={0}, two.input={1}".format(one.input, two.input))
one.input = 0
print("one.input={0}, two.input={1}".format(one.input, two.input))
Try to move
$ python Main.py
one.input=1
one.input=2, two.input=2
one.input=0, two.input=0
I see, it behaves like a global variable.
__new__
and __ init__
?__new__
(Hereafter, quoted from" Python language reference ")-** Called to create a new instance of class cls
. ** **
-** Take the class cls
, which is requested to instantiate, as the first argument. ** **
--The remaining arguments are passed to the object's constructor expression (class call statement).
-** The return value of __new__ ()
must be an instance of the new object (usually an instance of cls). ** **
--In a typical implementation, when creating a new instance of a class, specify the appropriate argument to super (). __ new__ (cls [, ...])
and use the super class's __new__ ()
method. Call it, make the necessary changes to the newly created instance, and then return it.
-** If __new__ ()
does not return an instance of cls
, the instance's__init __ ()
method will not be called. ** **
--The main purpose of __new__ ()
is to customize instantiation with subclasses of immutable types (int, str, tuple, etc.). It is also often overridden in custom metaclasses to customize class generation.
Called before the instance object is created, the first argument cls
is assigned a class object, and the purpose is to instantiate the object self
. Shin.
__new__
method between python2.7 series and python3 series. Web article: "How To Use Python new Method Example"__init__
(Hereafter, quoted from" Python language reference ")--Called after the instance is created (by __new__ ()
) and before it is returned to the caller.
--The argument is what you passed to the class's constructor expression.
--If both the base class and its derived class have __init __ ()
methods, the derived class's __init __ ()
method explicitly calls the base class's __init __ ()
method to make the base class part of the instance. Must be ensured that is properly initialized. For example, super () .__ init__ ([args ...]
).
--__new__ ()
and __init __ ()
work together to form an object (__new __ ()
creates and__init __ ()
customizes it), so it's not from__ init __ ()
Do not return a None
value; doing so will throw a TypeError at run time.
Called after the instance object is created, the instance object is assigned to the first argument self
, and the purpose is to initialize the object self
. ..
Try writing a Singleton without using the __new__
method.
Main.py
class Singleton(object):
@classmethod
def get_instance(cls, input):
if not hasattr(cls, "_instance"):
cls._instance = cls(input)
else:
cls._instance.input = input
return cls._instance
class Myclass(Singleton):
def __init__(self, input):
self.input = input
if __name__ == '__main__':
one = Myclass.get_instance(1)
print("one.input={0}".format(one.input))
two = Myclass.get_instance(2)
print("one.input={0}, two.input={1}".format(one.input, two.input))
one.input = 0
print("one.input={0}, two.input={1}".format(one.input, two.input))
Try to move
$ python Main.py
one.input=1
one.input=2, two.input=2
one.input=0, two.input=0
This style is simpler to use. I often see it in OpenStack or code reading.
-[Finishing "Introduction to Design Patterns Learned in Java Language" (Not)](https://medium.com/since-i-want-to-start-blog-that-looks-like-men-do/java Introduction to Design Patterns Learned in Language-Finishing-Not-2cc9b34a30b2) -Singleton pattern from "diary of tachikawa844"
Recommended Posts