Maison > Article > développement back-end > Quelles sont les manières courantes d’implémenter le modèle singleton en Python ?
class SingletonType(type): """ 单例元类。用于将普通类转换为单例类。 """ _instances = {} # 存储单例实例的字典 def __call__(cls, *args, **kwargs): """ 重写 __call__ 方法。用于创建和返回单例实例。 """ if cls not in cls._instances: # 如果类还没有实例化过 cls._instances[cls] = super().__call__(*args, **kwargs) # 则创建新实例并存储在字典中 return cls._instances[cls] # 返回字典中的实例 class MyClass(metaclass=SingletonType): """ 单例类。使用元类 SingletonType 将其转换为单例类。 """ def __init__(self, name): self.name = name def say_hello(self): print(f"Hello, my name is {self.name}.") # 创建 MyClass 的两个实例,应该是同一个对象 obj1 = MyClass("Alice") obj2 = MyClass("Bob") # 打印两个实例的内存地址,应该相同 print(hex(id(obj1))) # 输出:0x7f8d94547a90 print(hex(id(obj2))) # 输出:0x7f8d94547a90 # 调用两个实例的方法,输出应该相同 obj1.say_hello() # 输出:Hello, my name is Alice. obj2.say_hello() # 输出:Hello, my name is Alice.
Dans le code ci-dessus, nous définissons une métaclasse nommée SingletonType
et l'attribuons Utilisé comme métaclasse pour MyClass code>. Dans la classe <code>SingletonType
, nous maintenons un dictionnaire _instances
qui stocke des instances uniques de chaque classe. Dans la méthode __call__()
, nous vérifions le dictionnaire _instances
et si la classe n'a pas déjà d'instance, créons une nouvelle instance et l'ajoutons à _instances. Enfin, nous renvoyons les instances dans <code>_instances
. SingletonType
的元类,并将其用作 MyClass
的元类。在 SingletonType
类中,我们维护了一个 _instances
字典,用于存储每个类的唯一实例。在 __call__()
方法中,我们检查 _instances
字典,如果类尚未拥有实例,则创建一个新实例并添加到 _instances
中。最后,我们返回 _instances
中的实例。
在 MyClass
类中,我们定义了一个带参数的构造函数,并且使用 metaclass
参数来指定 SingletonType
元类。由于 MyClass
类使用 SingletonType
元类,因此它具有单例行为。在程序中,我们创建了 MyClass
的两个实例 obj1
和 obj2
,然后打印它们的内存地址以验证它们是否是同一个对象。最后,我们调用这两个实例的方法,输出应该相同。
def singleton(cls): """ 单例装饰器。用于将普通类转换为单例类。 """ instances = {} # 存储单例实例的字典 def get_instance(*args, **kwargs): """ 获取单例实例的方法。 """ if cls not in instances: # 如果类还没有实例化过 instances[cls] = cls(*args, **kwargs) # 则创建新实例并存储在字典中 return instances[cls] # 返回字典中的实例 return get_instance @singleton class MyClass: """ 单例类。使用装饰器 singleton 将其转换为单例类。 """ def __init__(self, name): self.name = name def say_hello(self): print(f"Hello, my name is {self.name}.") # 创建 MyClass 的两个实例,应该是同一个对象 obj1 = MyClass("Alice") obj2 = MyClass("Bob") # 打印两个实例的内存地址,应该相同 print(hex(id(obj1))) # 输出:0x7f8d94547a90 print(hex(id(obj2))) # 输出:0x7f8d94547
在上面的代码中,我们定义了一个名为 singleton
的装饰器函数。在 singleton
函数内部,我们创建了一个 instances
字典,用于存储每个类的唯一实例。然后,我们定义了一个名为 get_instance
的内部函数,用于获取单例实例。在 get_instance
函数中,我们检查 instances
字典,如果类尚未拥有实例,则创建一个新实例并添加到 instances
中。最后,我们返回字典中的实例。
在 MyClass
类上应用 @singleton
装饰器,以将其转换为单例类。由于该装饰器是针对类进行操作的,因此它可以轻松地将任何普通类转换为单例类。在程序中,我们创建了 MyClass
的两个实例 obj1
和 obj2
,然后打印它们的内存地址以验证它们是否是同一个对象。最后,我们调用这两个实例的方法,输出应该相同。
# mymodule.py class MyClass: """ 单例类。 """ def __init__(self, name): self.name = name def say_hello(self): print(f"Hello, my name is {self.name}.") my_singleton = MyClass("Alice") # 创建单例实例
# main.py from mymodule import my_singleton # 使用单例实例 my_singleton.say_hello() # 输出:Hello, my name is Alice.
在上面的代码中,我们将 MyClass
类定义在一个独立的模块 mymodule.py
中,并在其中创建了一个单例实例 my_singleton
。然后,在另一个文件 main.py
中,我们从 mymodule
模块中导入 my_singleton
实例,并使用它来调用 say_hello()
方法。
由于 Python 模块在首次导入时会自动执行,因此我们可以利用这一特性来创建单例实例。在 mymodule.py
模块中,我们可以确保 my_singleton
只会被创建一次,并在程序的其他部分中共享它。
class MyClass: """ 单例类。 """ _instance = None # 存储单例实例的类变量 def __new__(cls, *args, **kwargs): """ 重写 __new__ 方法。用于创建和返回单例实例。 """ if cls._instance is None: # 如果类还没有实例化过 cls._instance = super().__new__(cls) # 则创建新实例并存储在类变量中 return cls._instance # 返回类变量中的实例 def __init__(self, name): self.name = name def say_hello(self): print(f"Hello, my name is {self.name}.") # 创建 MyClass 的两个实例,应该是同一个对象 obj1 = MyClass("Alice") obj2 = MyClass("Bob") # 打印两个实例的内存地址,应该相同 print(hex(id(obj1))) # 输出:0x7f8d94547a90 print(hex(id(obj2))) # 输出:0x7f8d94547a90 # 调用两个实例的方法,输出应该相同 obj1.say_hello() # 输出:Hello, my name is Alice. obj2.say_hello() # 输出:Hello, my name is Alice.
在上面的代码中,我们将 MyClass
类的构造函数改为 __new__()
方法,并使用 _instance
类变量来存储单例实例。在 __new__()
方法中,我们检查 _instance
变量,如果类尚未拥有实例,则创建一个新实例并添加到 _instance
中。最后,我们返回 _instance
中的实例。
在程序中,我们创建了 MyClass
的两个实例 obj1
和 obj2
MyClass
, nous définissons un constructeur avec des paramètres et utilisons le paramètre metaclass
pour spécifier la métaclasse SingletonType
. Étant donné que la classe MyClass
utilise la métaclasse SingletonType
, elle a un comportement singleton. Dans le programme, nous créons deux instances de MyClass
, obj1
et obj2
, puis imprimons leurs adresses mémoire pour vérifier s'il s'agit du même objet. . Enfin, nous appelons la méthode sur les deux instances et le résultat devrait être le même. Décorateur : 🎜rrreee🎜Dans le code ci-dessus, nous définissons une fonction de décorateur nommée singleton
. Dans la fonction singleton
, nous créons un dictionnaire instances
qui stocke des instances uniques de chaque classe. Ensuite, nous définissons une fonction interne appelée get_instance
pour obtenir l'instance singleton. Dans la fonction get_instance
, nous vérifions le dictionnaire instances
et si la classe n'a pas déjà d'instance, créons une nouvelle instance et l'ajoutons aux instances
. Enfin, nous renvoyons l'instance dans le dictionnaire. 🎜🎜Appliquez le décorateur @singleton
sur la classe MyClass
pour la convertir en classe singleton. Puisque ce décorateur opère sur des classes, il peut facilement convertir n’importe quelle classe normale en classe singleton. Dans le programme, nous créons deux instances de MyClass
, obj1
et obj2
, puis imprimons leurs adresses mémoire pour vérifier s'il s'agit du même objet. . Enfin, nous appelons la méthode sur les deux instances et le résultat devrait être le même. 🎜🎜Module : 🎜rrreeerrreee🎜Dans le code ci-dessus, nous définissons la classe MyClass
dans un module indépendant mymodule.py
et la créons dedans. Une instance singleton my_singleton
. Ensuite, dans un autre fichier main.py
, nous importons l'instance my_singleton
du module mymodule
et l'utilisons pour appeler say_hello ()
méthode. 🎜🎜Étant donné que les modules Python sont automatiquement exécutés lors de la première importation, nous pouvons profiter de cette fonctionnalité pour créer des instances singleton. Dans le module mymodule.py
, nous pouvons garantir que my_singleton
n'est créé qu'une seule fois et le partager avec d'autres parties du programme. 🎜🎜nouvelle méthode : 🎜rrreee🎜Dans le code ci-dessus, nous changeons le constructeur de la classe MyClass
en méthode __new__()
et utilisons _instance
code> variable de classe pour stocker l’instance singleton. Dans la méthode __new__()
, nous vérifions la variable _instance
et si la classe n'a pas déjà d'instance, créons une nouvelle instance et l'ajoutons à _instance. Enfin, nous renvoyons l'instance dans <code>_instance
. 🎜🎜Dans le programme, nous créons deux instances de MyClass
, obj1
et obj2
, puis imprimons leurs adresses mémoire pour vérifier si elles sont identiques objet. Enfin, nous appelons la méthode sur les deux instances et le résultat devrait être le même. 🎜🎜Quelle que soit la méthode utilisée pour implémenter le modèle singleton, vous devez faire attention aux problèmes tels que la sécurité des threads et l'évolutivité. Par conséquent, lors du développement réel, veuillez examiner attentivement vos besoins et choisir une implémentation appropriée. 🎜Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!