Was sind die gängigen Methoden zur Implementierung des Singleton-Musters in Python?

WBOY
Freigeben: 2023-05-12 09:07:17
nach vorne
1033 Leute haben es durchsucht

Mehrere gängige Möglichkeiten, den Singleton-Modus in Python zu implementieren

Metaklasse:

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.
Nach dem Login kopieren

Im obigen Code definieren wir eine Metaklasse mit dem Namen SingletonType und weisen sie als Metaklasse für MyClass</code zu >. In der Klasse <code>SingletonType verwalten wir ein Wörterbuch _instances, das eindeutige Instanzen jeder Klasse speichert. In der Methode __call__() überprüfen wir das Wörterbuch _instances. Wenn die Klasse noch keine Instanz hat, erstellen wir eine neue Instanz und fügen sie zu _instances< hinzu /code>. Schließlich geben wir die Instanzen in <code>_instances zurück. SingletonType 的元类,并将其用作 MyClass 的元类。在 SingletonType 类中,我们维护了一个 _instances 字典,用于存储每个类的唯一实例。在 __call__() 方法中,我们检查 _instances 字典,如果类尚未拥有实例,则创建一个新实例并添加到 _instances 中。最后,我们返回 _instances 中的实例。

MyClass 类中,我们定义了一个带参数的构造函数,并且使用 metaclass 参数来指定 SingletonType 元类。由于 MyClass 类使用 SingletonType 元类,因此它具有单例行为。在程序中,我们创建了 MyClass 的两个实例 obj1obj2,然后打印它们的内存地址以验证它们是否是同一个对象。最后,我们调用这两个实例的方法,输出应该相同。

装饰器(Decorator):

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
Nach dem Login kopieren

在上面的代码中,我们定义了一个名为 singleton 的装饰器函数。在 singleton 函数内部,我们创建了一个 instances 字典,用于存储每个类的唯一实例。然后,我们定义了一个名为 get_instance 的内部函数,用于获取单例实例。在 get_instance 函数中,我们检查 instances 字典,如果类尚未拥有实例,则创建一个新实例并添加到 instances 中。最后,我们返回字典中的实例。

MyClass 类上应用 @singleton 装饰器,以将其转换为单例类。由于该装饰器是针对类进行操作的,因此它可以轻松地将任何普通类转换为单例类。在程序中,我们创建了 MyClass 的两个实例 obj1obj2,然后打印它们的内存地址以验证它们是否是同一个对象。最后,我们调用这两个实例的方法,输出应该相同。

模块(Module):

# 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")  # 创建单例实例
Nach dem Login kopieren
# main.py
from mymodule import my_singleton
# 使用单例实例
my_singleton.say_hello()  # 输出:Hello, my name is Alice.
Nach dem Login kopieren

在上面的代码中,我们将 MyClass 类定义在一个独立的模块 mymodule.py 中,并在其中创建了一个单例实例 my_singleton。然后,在另一个文件 main.py 中,我们从 mymodule 模块中导入 my_singleton 实例,并使用它来调用 say_hello() 方法。

由于 Python 模块在首次导入时会自动执行,因此我们可以利用这一特性来创建单例实例。在 mymodule.py 模块中,我们可以确保 my_singleton 只会被创建一次,并在程序的其他部分中共享它。

new 方法:

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.
Nach dem Login kopieren

在上面的代码中,我们将 MyClass 类的构造函数改为 __new__() 方法,并使用 _instance 类变量来存储单例实例。在 __new__() 方法中,我们检查 _instance 变量,如果类尚未拥有实例,则创建一个新实例并添加到 _instance 中。最后,我们返回 _instance 中的实例。

在程序中,我们创建了 MyClass 的两个实例 obj1obj2

In der Klasse MyClass definieren wir einen Konstruktor mit Parametern und verwenden den Parameter metaclass, um die Metaklasse SingletonType anzugeben. Da die Klasse MyClass die Metaklasse SingletonType verwendet, weist sie Singleton-Verhalten auf. Im Programm erstellen wir zwei Instanzen von MyClass, obj1 und obj2, und geben dann ihre Speicheradressen aus, um zu überprüfen, ob es sich um dasselbe Objekt handelt . Schließlich rufen wir die Methode in beiden Instanzen auf und die Ausgabe sollte dieselbe sein.

Decorator: 🎜rrreee🎜Im obigen Code definieren wir eine Decorator-Funktion namens singleton. Innerhalb der singleton-Funktion erstellen wir ein instances-Wörterbuch, das eindeutige Instanzen jeder Klasse speichert. Dann definieren wir eine interne Funktion namens get_instance, um die Singleton-Instanz abzurufen. In der Funktion get_instance überprüfen wir das Wörterbuch instances. Wenn die Klasse noch keine Instanz hat, erstellen wir eine neue Instanz und fügen sie zu instanceshinzu >. Schließlich geben wir die Instanz im Wörterbuch zurück. 🎜🎜Wenden Sie den Dekorator @singleton auf die Klasse MyClass an, um sie in eine Singleton-Klasse umzuwandeln. Da dieser Dekorator mit Klassen arbeitet, kann er problemlos jede normale Klasse in eine Singleton-Klasse umwandeln. Im Programm erstellen wir zwei Instanzen von MyClass, obj1 und obj2, und geben dann ihre Speicheradressen aus, um zu überprüfen, ob es sich um dasselbe Objekt handelt . Schließlich rufen wir die Methode in beiden Instanzen auf und die Ausgabe sollte dieselbe sein. 🎜🎜Modul: 🎜rrreeerrreee🎜Im obigen Code definieren wir die Klasse MyClass in einem unabhängigen Modul mymodule.py und erstellen darin eine Singleton-Instanz my_singleton . Dann importieren wir in einer anderen Datei main.py die Instanz my_singleton aus dem Modul mymodule und rufen damit say_hello () auf. -Methode. 🎜🎜Da Python-Module beim ersten Import automatisch ausgeführt werden, können wir diese Funktion nutzen, um Singleton-Instanzen zu erstellen. Im Modul mymodule.py können wir sicherstellen, dass my_singleton nur einmal erstellt wird, und es mit anderen Teilen des Programms teilen. 🎜🎜neue Methode: 🎜rrreee🎜Im obigen Code ändern wir den Konstruktor der Klasse MyClass in die Methode __new__() und verwenden _instanceCode> Klassenvariable zum Speichern der Singleton-Instanz. In der Methode __new__() überprüfen wir die Variable _instance und wenn die Klasse noch keine Instanz hat, erstellen wir eine neue Instanz und fügen sie zu _instance. Schließlich geben wir die Instanz in <code>_instance zurück. 🎜🎜Im Programm erstellen wir zwei Instanzen von MyClass, obj1 und obj2, und drucken dann ihre Speicheradressen aus, um zu überprüfen, ob sie identisch sind Objekt. Schließlich rufen wir die Methode in beiden Instanzen auf und die Ausgabe sollte dieselbe sein. 🎜🎜Unabhängig davon, welche Methode zur Implementierung des Singleton-Musters verwendet wird, müssen Sie auf Aspekte wie Thread-Sicherheit und Skalierbarkeit achten. Bitte prüfen Sie daher bei der tatsächlichen Entwicklung sorgfältig Ihre Anforderungen und wählen Sie eine geeignete Implementierung aus. 🎜

Das obige ist der detaillierte Inhalt vonWas sind die gängigen Methoden zur Implementierung des Singleton-Musters in Python?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:yisu.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!