6

Python アプリケーションで広く使用されており、グローバル インスタンスを 1 つだけ持つ必要があるいくつかのクラスがあります (Logger、DbConnection など)。Python はクラス内の静的変数/メソッドをサポートしていないため、ここでシングルトンを作成する通常の Java/C++ の方法は機能しません。Python でシングルトンを実装するための代替手段を探しました。私は単純な (できればメタプログラミングを使わない) クリーンな実装を望んでいます。これは良さそうです:

class MyClass(object):
    def a():
        pass

singleton = MyClass()

シングルトンの使用は次のように簡単です

import myClass
myClass.singleton.a()

オブジェクトの初期化がそれほど単純でない場合は、直接割り当てを作成関数に置き換えることができます。

モジュール スコープで getInstance() を作成し、常にそれを使用して myObj を取得することもできます。

質問 1) これは正常に動作しますか? モジュール コード (myObj 割り当て) は、他のモジュールに初めてインポートされたときにのみ実行され、このモジュールをどこかにインポートするたびに myObj が作成されるわけではありませんか?

私が見た別の方法は、グローバル モジュールを使用することです。何かのようなもの:

from myClass1 import MyClass1
from myClass2 import MyClass2

myObj1 = MyClass1()
myObj2 = MyClass2()

これを使用して:

import globals
globals.myObj1.a()

私は最初の選択肢を好む傾向があります。

質問 2) 2 つのソリューションのうち、推奨するソリューションはどれですか?

質問 3) 3 番目の解決策は、Logger などの広く普及しているオブジェクトを複数のクラス/関数に渡すことですが、これは良い解決策ではありません。ここに記載されていないより良い解決策はありますか?

グローバル変数とシングルトンを使用することの欠点を認識しています。ただし、グローバルな状態を持つことは、私のアプリケーションでは大きな問題ではありません。コードが明確で使いやすいソリューションを好みます。

4

3 に答える 3

5

loggerインスタンスを 1 つだけ持つクラスが必要な場合は、別のモジュールにします。

# In logging.py
def log(msg):
  print msg

次に、ログインする任意のスクリプトから。

from logging import log
log("A critical error occured.")
于 2012-08-22T04:27:13.563 に答える
0

以下を作成することを検討してください。

  1. 州のクラス
  2. プロキシクラス

状態クラスは、 init.pyモジュールで初期化されるスレッドを作成します。状態クラスには、クラスインスタンスをスレッドに渡し、weakrefをスレッドに保存するメソッドがあります。

後で、プロキシクラスを使用して、スレッド内のクラスインスタンスにアクセスできます。クラスオブジェクトが作成されていない場合、プロキシは目的のクラスのインスタンスを作成し、それをスレッドに保存します。

このパターンを使用すると、各クラスのインスタンスの数を1に制限し、アプリケーションの一部が実行されているときはいつでも、グローバルに繰り返し使用する必要のあるインスタンスを再作成する必要がないようにすることができます。

于 2012-08-22T04:34:40.250 に答える
-1

シングルトンの作り方の正解は?しないでください。それを使用する必要があるすべてのものへの参照を明示的に渡す必要があります。ファクトリ関数、ラッパー クラスなどを使用して労力を軽減できます。

screen や logger のように本質的にグローバルなものがある場合でも、単体テストを可能にするために明示的に渡す必要があります。これは、最終的なデザインの一部になることを意図したものにのみ適用されることに注意してください。ロガーがデバッグのための簡単なハックである場合は、遠慮なくグローバルにしてください。

于 2012-08-22T04:17:16.953 に答える