Python のシングルトンデザインパターン

Manav Narula 2023年1月30日
  1. Python でデコレータを使用してシングルトンデザインパターンを実装する
  2. Python で基本クラスを使用してシングルトンデザインパターンを実装する
  3. Python でメタクラスを使用してシングルトンデザインパターンを実装する
  4. Python でモジュールを使用してシングルトンデザインパターンを実装する
Python のシングルトンデザインパターン

デザインパターンは、問題を解決するためのコードを表すことができます。シングルトンはそのようなデザインパターンの 1つであり、Python でクラスのさまざまなオブジェクトを作成できます。

このパターンは、特定のクラスの 1つのオブジェクトのみを制限します。Python でこのパターンをシミュレートする方法はいくつかあります。

Python でデコレータを使用してシングルトンデザインパターンを実装する

Python のデコレータは、他の関数やオブジェクトを引数として取り、それらの動作を変更できる関数です。デコレータを使用するには、@記号を使用します。

それらを使用して、シングルトンデザインパターンを実装できます。

次の例を参照してください。

def singleton_dec(class_):
    instances = {}

    def getinstance(*args, **kwargs):
        if class_ not in instances:
            instances[class_] = class_(*args, **kwargs)
        return instances[class_]

    return getinstance


@singleton_dec
class Sample:
    def __init__(self):
        print("Object created.")


x = Sample()
y = Sample()
print(x, y)

出力:

Object created.
<__main__.Sample object at 0x0000015E72D3CA48> <__main__.Sample object at 0x0000015E72D3CA48>

上記の例では、クラス全体を引数として取るデコレータを作成しました。このデコレータを使用すると、シングルトンオブジェクトを実装できます。これは、xy の位置で確認できます。

シングルトンにデコレータを使用することの欠点は、最終クラス Sample が関数になるため、クラスメソッドを使用できないことです。

Python で基本クラスを使用してシングルトンデザインパターンを実装する

基本クラスは、他のクラスを派生させる特別なクラスです。この基本クラスのインスタンスは作成されません。

基本クラスを使用して、Python でシングルトンの構造を提供できます。

例えば、

class Singleton_base(object):
    _instance = None

    def __new__(class_, *args, **kwargs):
        if not isinstance(class_._instance, class_):
            class_._instance = object.__new__(class_, *args, **kwargs)
        return class_._instance


class Sample1(Singleton_base):
    def __init__(self):
        print("Object created.")


x = Sample1()
y = Sample1()
print(x, y)

出力:

Object created.
Object created.
<__main__.Sample object at 0x0000015E72D3F388> <__main__.Sample object at 0x0000015E72D3F388>

これは効果的な方法です。ただし、多重継承が原因で複数のクラスが関与する場合はエラーが発生する可能性があります。

Python でメタクラスを使用してシングルトンデザインパターンを実装する

メタクラスは、クラスのオブジェクトの動作を定義できるため、Python の非常に興味深い機能です。クラスのクラスと言えます。

Python 2 では、クラスに __metaclass__ 属性を追加します。Python 3 では、クラスの引数として追加できます。

この機能を使用して、Python でシングルトンデザインを実装できます。

例えば、

class Singleton_meta(type):
    _instances = {}

    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(Singleton_meta, cls).__call__(*args, **kwargs)
        return cls._instances[cls]


class Sample(metaclass=Singleton_meta):
    def __init__(self):
        print("Object created.")


x = Sample()
y = Sample()
print(x, y)

出力:

Object created.
<__main__.Sample object at 0x0000015E72D3FF88> <__main__.Sample object at 0x0000015E72D3FF88>

これはメタクラスの適切なアプリケーションであり、自動継承を実現します。

Python でモジュールを使用してシングルトンデザインパターンを実装する

おそらく、Python でのシングルトンの最も簡単で最も基本的な実装は、モジュールを使用することです。

Python でモジュールを作成できることはわかっています。関数のみを含むモジュールはシングルトンとして機能できます。これは、これらすべての関数をモジュールにバインドするためです。

著者: Manav Narula
Manav Narula avatar Manav Narula avatar

Manav is a IT Professional who has a lot of experience as a core developer in many live projects. He is an avid learner who enjoys learning new things and sharing his findings whenever possible.

LinkedIn