2

私はちょうどネットに出くわし、これらの興味深いコードが切り取られているのを見つけました:

http://code.activestate.com/recipes/66531/

class Borg:
    __shared_state = {}
    def __init__(self):
        self.__dict__ = self.__shared_state
    # and whatever else you want in your class -- that's all!

シングルトンが何であるかは理解していますが、特定のコードが切り取られていることは理解していません。「__shared_state」がどのように/どこで変更されるのか説明してもらえますか?

ipythonで試しました:

In [1]: class Borg:
   ...:         __shared_state = {}
   ...:     def __init__(self):
   ...:             self.__dict__ = self.__shared_state
   ...:     # and whatever else you want in your class -- that's all!
   ...: 
In [2]: b1 = Borg()
In [3]: b2 = Borg()
In [4]: b1.foo="123"
In [5]: b2.foo
Out[5]: '123'
In [6]: 

しかし、これがどのように起こるかを完全に理解することはできません。

4

3 に答える 3

12

クラスのインスタンスはdict__dict__に等しく設定されているためです。それらは同じオブジェクト__share_stateを指しています。(すべてのクラス属性を保持します)Classname.__dict__

あなたがするとき:

b1.foo = "123"

dictその両方b1.__dict__を変更してBorg.__shared_state参照しています。

于 2012-08-26T05:58:00.887 に答える
3

インスタンスは別個のオブジェクトですが、それらの__dict__属性を同じ値に設定することにより、インスタンスは同じ属性ディクショナリを持ちます。Python は、属性ディクショナリを使用してオブジェクトのすべての属性を格納します。したがって、属性に対するすべての変更は共有属性ディクショナリに対して行われるため、実質的に 2 つのインスタンスは同じように動作します。

isただし、同等性 (浅い同等性) をテストするためにを使用する場合、オブジェクトは依然として別個のインスタンスであるため、等しくありません (思考を共有するが物理的に異なる個々のボーグ ドローンによく似ています)。

于 2012-08-26T06:08:53.853 に答える
3

オブジェクトをインスタンス化した後に呼び出されるメソッドは、新しく作成されたオブジェクトの属性をクラス属性に__init__置き換えます。__dict____shared_state

a.__dict__b.__dict__およびBorg._Borg__shared_stateすべて同じオブジェクトです。_Borgクラスの外部からプライベート属性にアクセスするときは、暗黙のプレフィックスを追加する必要があることに注意してください。

In [89]: a.__dict__ is b.__dict__ is Borg._Borg__shared_state
Out[89]: True
于 2012-08-26T06:03:15.903 に答える