[GO] Lernen Sie das Entwurfsmuster "Singleton" mit Python

Als Material zum Erlernen von GoF-Entwurfsmustern scheint das Buch "Einführung in Entwurfsmuster, die in der erweiterten und überarbeiteten Java-Sprache gelernt wurden" hilfreich zu sein. Da die aufgeführten Beispiele jedoch auf JAVA basieren, habe ich dieselbe Vorgehensweise mit Python versucht, um mein Verständnis zu vertiefen.

■ Singleton

Das Singleton-Muster ist eines der Entwurfsmuster in einem objektorientierten Computerprogramm. Definiert von der GoF (Gang of Four). Das Singleton-Muster ist ein Entwurfsmuster, das garantiert, dass nur eine Instanz der Klasse erstellt wird. Wird verwendet, um Mechanismen zu implementieren, die in der gesamten Anwendung absolut einheitlich sein müssen, z. B. Gebietsschema und Erscheinungsbild 600px-Singleton_UML_class_diagram.svg.png (Das Obige wird aus Wikipedia zitiert)

■ Beispielprogramm "Singleton"

Definieren wir eine Klasse, die nur eine Instanz erstellen kann.

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))

Versuche dich zu bewegen

$ python Main.py 
one.input=1
one.input=2, two.input=2
one.input=0, two.input=0

Ich sehe, es verhält sich wie eine globale Variable.

□ Memorandum

(1) Was ist der Unterschied zwischen "new" und "init"?

1. Im Fall von __new__ [(im Folgenden aus" Python-Sprachreferenz "zitiert)]](https://docs.python.org/ja/3/reference/datamodel.html?highlight=new#object.new)

Wird aufgerufen, bevor das Instanzobjekt erstellt wird, wird dem ersten Argument "cls" ein Klassenobjekt zugewiesen, und der Zweck besteht darin, das Objekt "self" zu instanziieren. Schienbein.

2. Im Fall von __init __ (im Folgenden aus" Python-Sprachreferenz "zitiert)

  • Wird aufgerufen, nachdem die Instanz erstellt wurde (von __new__ ()) und bevor sie an den Aufrufer zurückgegeben wird.
  • Das Argument ist das, was Sie an den Konstruktorausdruck der Klasse übergeben haben. --Wenn sowohl die Basisklasse als auch ihre abgeleitete Klasse eine __init __ () -Methode haben, ruft die __init __ () -Methode der abgeleiteten Klasse explizit die __init __ () -Methode der Basisklasse auf, um die Basisklasse zu einem Teil der Instanz zu machen. Muss sichergestellt sein, dass es richtig initialisiert ist. Zum Beispiel super () .__ init__ ([args ...]). --__new__ () und__init __ ()arbeiten zusammen, um ein Objekt zu bilden (__new__ ()erstellt und __init __ () passt es an), es ist also nicht von__ init__ () Geben Sie keinen "None" -Wert zurück. Andernfalls wird zur Laufzeit ein TypeError ausgelöst.

Wird aufgerufen, nachdem das Instanzobjekt erstellt wurde. Das Instanzobjekt wird dem ersten Argument "self" zugewiesen. Der Zweck besteht darin, das Objekt "self" zu initialisieren. ..

(2) Versuchen Sie, die ursprüngliche "Einzeltonne" zu schreiben.

Versuchen Sie, einen Singleton zu schreiben, ohne die Methode "new" zu verwenden.

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))

Versuche dich zu bewegen

$ python Main.py 
one.input=1
one.input=2, two.input=2
one.input=0, two.input=0

Dieser Stil ist einfacher zu verwenden. Ich sehe es oft in OpenStack oder beim Lesen von Code.

■ Referenz-URL

Recommended Posts