9

Python でのシングルトン パターンの使用に関連する多くの質問があります。この質問は、既に説明した側面の多くを繰り返す可能性がありますが、次の特定の質問に対する答えは見つかりませんでした。

MyClass一度だけインスタンス化したいクラスがあるとしましょう。Pythonでは、コードで次のようにこれを行うことができますmyclass.py:

class MyClass(object): 
    def foo(self):
        ....


instance = MyClass()

次に、他のプログラムでは、インスタンスを簡単に参照できます

import myclass
myclass.instance.foo()

このアプローチはどのような状況で十分ですか? シングルトン パターンの使用はどのような状況で有用/必須ですか?

4

3 に答える 3

7

シングルトン パターンは、多くの場合、要件よりも利便性の問題です。Python は、他の言語と比較して、テストでシングルトンをモックアウトするのがかなり簡単であるという点で、他の言語とは少し異なります (グローバル変数を上書きするだけです!)。利便性のためにこれを行っているのでしょうか、それともインスタンスが 1 つしかないことが厳密に必要なためですか? 将来的に複数になる可能性はありますか?

実際に 1 回だけ構築されるクラスを作成する場合は、状態をモジュールの一部にし、そのメソッドをモジュール レベルの関数にする方が理にかなっている場合があります。正確に 1 つのインスタンスの仮定が将来変更される可能性がある場合は、グローバル名を介してシングルトンを参照するよりも、シングルトン インスタンスを渡す方がはるかに優れていることがよくあります。

たとえば、次の方法で「シングルトン」を簡単に実装できます。

if __name__ == '__main__':
   instance = MyClass()
   doSomethingWith(instance)

上記では、「インスタンス」は一度しか構築されないという事実によりシングルトンですが、それを処理するコードは を参照するのではなくインスタンスを提供されますmodule.instance。これにより、コードの一部を再利用しやすくなります。状況によっては、複数の が必要ですMyClass

于 2013-01-30T09:08:14.773 に答える
3

Michael Aaron Safyan が提案するように、モジュールをシングルトンとして使用したいと仮定すると、次のようなことを行うことで、モジュールがメイン コードによってインポートされていなくても機能させることができます (メイン コードまたはインポートするモジュール内)。直接的または間接的に)。これが行うことは、instanceクラス属性を 1 に初期化してから、モジュール オブジェクトをsys.modules作成されたインスタンスに置き換えることです。

class _MyClass(object):
    def foo(self):
        print 'foo()'

_MyClass.instance = _MyClass()

import sys
_ref = sys.modules[__name__]  # Reference to current module so it's not deleted
sys.modules[__name__] = _MyClass.instance

シングルトンは、クラス ファクトリのクラスのグループ、定数のグループ、構成情報のバンドルなど、1 つのみ (レジストリ) を持つことが理にかなっている場合に、物事の「レジスタ」を実装する便利な方法であることがわかりました。 . 多くの場合、通常の Python モジュールだけで問題ありません。これは、デフォルトsys.modulesでは、すでに読み込まれているモジュールがディクショナリにキャッシュされるため、事実上すでにシングルトンになっているためです。

ただし、場合によっては、構築パラメータを渡すことができ、プロパティを持つことができるため、クラス インスタンスが望ましい場合があります。これは、組み込みのモジュール オブジェクトにはないものであり、所有させることもできません。このような制限は、カスタム クラス インスタンスを効果的にモジュール オブジェクトに変換する上記のトリックを使用して回避できます。

クラス インスタンスをモジュール オブジェクトとして使用するというアイデアは、Alex MartelliActiveStateレシピ「 Constants in Python 」に由来します。

于 2013-01-30T11:27:29.200 に答える
1

私の謙虚な意見では、シングルトン パターンには 2 つの側面があります。

  • 複数は意味がないため、特定のサービスに対して単一のコンテキストが必要です。
  • サービスが壊れる可能性があるため、特定のタイプの2つのオブジェクトを作成することを絶対に防ぎたい

最初のケースにはいくつかのアプリケーション (ログ サービス) がある可能性がありますが、2 番目のケースは多くの場合、設計が悪いことを示しています。

ユーザーがこの問題について考える必要がないように、API を設計する必要があります。しかし、文書化されていないレイヤーを掘り下げて非表示のコンストラクターを見つけ、何らかの理由でそれを使用したい場合、必要なことを実行するのを防ぐために作成された役に立たない構成体に対処する必要はありません。

于 2013-01-30T09:12:42.463 に答える