3

私が使用しているPython記述子は、その所有者クラスのすべてのインスタンス間でその値を共有しています。各インスタンスの記述子に独自の内部値を含めるにはどうすればよいですか?

class Desc(object):
    def __init__(self, initval=None,name='val'):
        self.val = initval
        self.name = name

    def __get__(self,obj,objtype):
        return self.val

    def __set__(self,obj,val):
        self.val = val

    def __delete__(self,obj):
        pass


class MyClass(object):
    desc = Desc(10,'varx')

if __name__ == "__main__":
    c = MyClass()
    c.desc = 'max'
    d = MyClass()
    d.desc = 'sally'

    print(c.desc)
    print(d.desc)

出力は次のとおりです。最後の呼び出しで両方のオブジェクトの値が設定されます。

localhost $ python descriptor_testing.py 
sally
sally
4

1 に答える 1

7

クラスオブジェクトに格納されている記述子オブジェクトは1つだけなので、self常に同じです。オブジェクトごとにデータを保存し、記述子を介してアクセスする場合は、各オブジェクトにデータを保存するか(おそらくより良いアイデア)、各オブジェクトによってキー設定されたデータ構造にデータを保存する必要があります(私は好きではありません)。できるだけ多く)。

インスタンスオブジェクトにデータを保存します。

class Desc(object):
    default_value = 10
    def __init__(self, name):
        self.name = name

    def __get__(self,obj,objtype):
        return obj.__dict__.get(self.name, self.default_value)
        # alternatively the following; but won't work with shadowing:
        #return getattr(obj, self.name, self.default_value)

    def __set__(self,obj,val):
        obj.__dict__[self.name] = val
        # alternatively the following; but won't work with shadowing:
        #setattr(obj, self.name, val)

    def __delete__(self,obj):
        pass


class MyClass(object):
    desc = Desc('varx')

この場合、データはobjそのの's'varx'エントリに格納されます__dict__。ただし、データ記述子のルックアップがどのように機能するかにより、記述子を使用してストレージの場所を「シャドウ」することができます。

class MyClass(object):
    varx = Desc('varx')

この場合、ルックアップを実行すると、次のようになります。

MyClass().varx

記述子オブジェクトが呼び出されてルックアップを実行できますが、ルックアップが次のようになると次のようになります。

MyClass().__dict__['varx']

値は直接返されます。したがって、記述子は、いわば「隠された」場所にデータを格納できます。

于 2009-12-16T16:11:00.117 に答える