8

__set__以下のクラスBでは、に値を割り当てるたびにクラスAの関数が呼び出されるようにしたかったのB().aです。代わりに、値を設定して値をB().a上書きB().aします。クラスCの割り当てはC().a正しく機能しますが、ユーザークラスごとにAの個別のインスタンスが必要でした。つまり、C()の1つのインスタンスで「a」を変更して他のすべてのインスタンスで「a」を変更したくないのです。問題を説明するために、いくつかのテストを作成しました。test1とtest2の両方に合格するクラスを定義するのを手伝ってもらえますか?

class A(object):
    def __set__(self, instance, value):
        print "__set__ called: ", value

class B(object):
    def __init__(self):
        self.a = A()

class C(object):
    a = A()

def test1( class_in ):
    o = class_in()
    o.a = "test"
    if isinstance(o.a, A):
        print "pass"
    else:
        print "fail"

def test2( class_in ):
    o1, o2 = class_in(), class_in()
    if o1.a is o2.a:
        print "fail"
    else:
        print "pass"
4

3 に答える 3

5

ドキュメントに従って:

次のメソッドは、そのメソッドを含むクラス (いわゆる記述子クラス) のインスタンスが、所有者クラスと呼ばれる別の新しいスタイル クラスのクラス ディクショナリにある場合にのみ適用されます。以下の例では、「属性」は、その名前が所有者クラスのプロパティのキーである属性を指します。記述子は、新しいスタイルのクラス自体としてのみ実装できます。__dict__

したがって、インスタンスに記述子を含めることはできません。

ただし、記述子はアクセスに使用されているインスタンスへの参照を取得するため、それを状態を格納するためのキーとして使用するだけで、インスタンスに応じて異なる動作を行うことができます。

于 2009-06-16T22:29:29.983 に答える
0

記述子によって管理される属性を持つオブジェクトをクラス化したいという点で、私は同様の問題に悩まされていました。これを行ったとき、属性がすべてのオブジェクトで上書きされており、それらが個別ではないことに気付きました。

私はSOの質問を提起し、結果の答えは次のとおりです: class attribute changing value for no reason

記述子について説明している適切なドキュメント リンクは次のとおりです: http://martyalchin.com/2007/nov/24/python-descriptors-part-2-of-2/

前述のリンクからの記述子の例を以下に示します。

class Numberise(object):
    def __init__(self, name):
        self.name = name

    def __get__(self, instance, owner):
        if self.name not in instance.__dict__:
            raise (AttributeError, self.name)
        return '%o'%(instance.__dict__[self.name])

    def __set__(self, instance, value):
        print ('setting value to: %d'%value)
        instance.__dict__[self.name] = value
于 2014-03-08T02:53:21.117 に答える
0

元のテストに合格できるクラスを次に示しますが、ほとんどの状況では使用しないでください。それ自体の isinstance テストに失敗します。

class E(object):
    def __new__(cls, state):
        class E(object):
            a = A(state)
            def __init__(self, state):
                self.state = state
        return E(state)

#>>> isinstance(E(1), E)
#False
于 2009-06-17T00:12:40.103 に答える