Apprenez le modèle de conception "Singleton" avec Python

En tant que matériel d'apprentissage des modèles de conception du GoF, le livre «Introduction aux modèles de conception appris dans le langage Java augmenté et révisé» semble être utile. Cependant, comme les exemples repris sont basés sur JAVA, j'ai essayé la même pratique avec Python pour approfondir ma compréhension.

■ Singleton

Le modèle Singleton est l'un des modèles de conception d'un programme informatique orienté objet. Défini par le GoF (Gang of Four). Le modèle Singleton est un modèle de conception qui garantit qu'une seule instance de la classe sera créée. Utilisé pour implémenter des mécanismes qui doivent être absolument unifiés dans toute l'application, tels que les paramètres régionaux et l'apparence 600px-Singleton_UML_class_diagram.svg.png (Ce qui précède est cité sur Wikipedia)

■ Exemple de programme "Singleton"

Définissons une classe qui ne peut créer qu'une seule 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))

Essayez de bouger

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

Je vois, il se comporte comme une variable globale.

□ Mémorandum

(1) Quelle est la différence entre «new» et «init»?

1. Dans le cas de __new__ (ci-après, cité de" Python language reference ")

Appelé avant la création de l'objet d'instance, le premier argument cls reçoit un objet de classe, et le but est d'instancier l'objet self. Tibia.

2. Dans le cas de __init__ (ci-après, cité de" Python language reference ")

  • Appelé après la création de l'instance (par __new__ ()) et avant qu'elle ne soit renvoyée à l'appelant.
  • L'argument est ce que vous avez passé à l'expression du constructeur de la classe. --Si la classe de base et sa classe dérivée ont une méthode __init __ (), la méthode __init __ () de la classe dérivée appelle explicitement la méthode __init __ () de la classe de base pour faire de la classe de base une partie de l'instance. Doit être assuré qu'il est correctement initialisé. Par exemple, super () .__ init__ ([args ...]). --__new__ () et__init __ ()travaillent ensemble pour former un objet (__new__ ()crée et __init __ () le personnalise), donc ce n'est pas de__ init__ () Ne renvoyez pas une valeur «None»; cela lèvera une TypeError au moment de l'exécution.

Appelé après la création de l'objet d'instance, l'objet d'instance est affecté au premier argument «self», et le but est d'initialiser l'objet «self». ..

(2) Essayez d'écrire l'original "Tonne unique"

Essayez d'écrire un Singleton sans utiliser la méthode __new__.

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

Essayez de bouger

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

Ce style est plus simple à utiliser. Je le vois souvent dans OpenStack ou en lecture de code.

■ URL de référence

Recommended Posts