ホームページ >バックエンド開発 >Python チュートリアル >Python でシングルトン パターンを実装する一般的な方法は何ですか?

Python でシングルトン パターンを実装する一般的な方法は何ですか?

WBOY
WBOY転載
2023-05-12 09:07:171061ブラウズ

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.

上記のコードでは、SingletonType のメタクラスという名前のクラスを定義し、それを使用しますMyClass のメタクラスとして。 SingletonType クラスでは、各クラスの一意のインスタンスを格納する _instances ディクショナリを維持します。 __call__() メソッドでは、_instances ディクショナリを確認し、クラスにまだインスタンスがない場合は、新しいインスタンスを作成して _instances に追加します。 。最後に、_instances のインスタンスを返します。

MyClass クラスでは、パラメーターを含むコンストラクターを定義し、metaclass パラメーターを使用して SingletonType メタクラスを指定します。 MyClass クラスは SingletonType メタクラスを使用するため、シングルトン動作を行います。プログラムでは、MyClassobj1obj2 の 2 つのインスタンスを作成し、それらのメモリ アドレスを出力して、それらが同じオブジェクトであるかどうかを確認します。最後に、両方のインスタンスでメソッドを呼び出します。出力は同じになるはずです。

デコレータ:

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 に追加します。最後に、辞書内のインスタンスを返します。

@singleton デコレータを MyClass クラスに適用して、シングルトン クラスに変換します。このデコレータはクラスを操作するため、通常のクラスをシングルトン クラスに簡単に変換できます。プログラムでは、MyClassobj1obj2 の 2 つのインスタンスを作成し、それらのメモリ アドレスを出力して、それらが同じオブジェクトであるかどうかを確認します。最後に、両方のインスタンスでメソッドを呼び出します。出力は同じになるはずです。

モジュール:

# 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.

上記のコードでは、独立したモジュール mymodule.pyMyClass クラスを定義し、シングルトン インスタンスを作成しました。 my_singleton がその中にあります。次に、別のファイル main.py で、mymodule モジュールから my_singleton インスタンスをインポートし、それを使用して say_hello()方法。

Python モジュールは最初にインポートされるときに自動的に実行されるため、この機能を利用してシングルトン インスタンスを作成できます。 mymodule.py モジュールでは、my_singleton が 1 回だけ作成され、プログラムの他の部分間で共有されるようにすることができます。

新しいメソッド:

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 obj1obj2 の 2 つのインスタンスを作成し、それらのメモリ アドレスを出力して、それらが同じオブジェクト。最後に、両方のインスタンスでメソッドを呼び出します。出力は同じになるはずです。

シングルトン パターンの実装にどの方法を使用する場合でも、スレッドの安全性やスケーラビリティなどの問題に注意を払う必要があります。したがって、実際の開発では、ニーズを慎重に検討し、適切な実装を選択してください。

以上がPython でシングルトン パターンを実装する一般的な方法は何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。