3

ホスト オブジェクトの辞書にデータを格納する記述子があります。そして、クラス階層に同じ名前のこの記述子のフィールドがあります。

class ADescriptor(object):
    def __init__(self, keyname='descr'):
        self.keyname = keyname

    def __get__(self, obj, objtype):
        return getattr(obj, self.keyname, 8192 )

    def __set__(self, obj, val):
        setattr(obj, self.keyname, val)

class A(object):
    f = ADescriptor('keyA')

class B(A):
    f = ADescriptor('keyB')

b = B()
b.f = 'b'
print super(B,b).f
super(B,b).f = 'a'

最後の行は機能しません: super(B,b).f = 'a'

なぜ機能し、類似のセットが機能しないのですか? A. dict ['f']よりもエレガントな方法で A の f を設定できますか。(b,'a') を設定しますか?


訂正:

私の最初の投稿で与えられた形式では、Af は A のキー名の名前付きプロパティ (欠落) またはデフォルト 8192 に評価されます - それとは何の関係もありません。そのため、A. dict ['f'] - を使用してget呼び出しを除外しました。Af を必要な ADescriptor インスタンスに評価できるようにするには、わずかな変更が必要でした。

def __get__(self, obj, objtype=None):
    if not obj:      #return descriptor itself if no bound object given
        return self
    return getattr(obj, self.keyname, 8192 )

この場合A.f.__set__(b,'a')は機能します。しかし、それはまだ醜いです!@BiggAl が提供するプロパティ ソリューションは、私のニーズには適していません。すべての記述子をプロパティでラップする必要があります。

4

1 に答える 1

1

A.f.__set__(b,'a')うまくいけばきっとうまくA.__dict__['f'].__set__(b,'a')いくでしょうか?そして、A.f.b = 'a'私の記憶が私に役立つなら、あなたはそれをプロパティとして指定しなければならないかもしれませんが、それからうまくいくことさえありません。


歴史を見て、巨大なブレインファートを見てください...

>>> class ADescriptor(object):
    def __init__(self, keyname='descr'):
        self.keyname = keyname
    def __get__(self, obj, objtype):
        return (self.keyname, getattr(obj, self.keyname, 8192 ))
    def __set__(self, obj, val):
        setattr(obj, self.keyname, val)

>>> class A(object):
    f = ADescriptor('keyA')


>>> class B(A):
        f = ADescriptor('keyB')


>>> a, b = A(), B()
>>> print (a.f, b.f, A.f, B.f)
(('keyA', 8192), ('keyB', 8192), ('keyA', 8192), ('keyB', 8192))
>>> b.f = 'b'
>>> print (a.f, b.f, A.f, B.f)
(('keyA', 8192), ('keyB', 'b'), ('keyA', 8192), ('keyB', 8192))
>>> A.f = 'a'
>>> print (a.f, b.f, A.f, B.f)
('a', ('keyB', 'b'), 'a', ('keyB', 8192))
>>> 

これはあなたが正しいことですか?(__get__デバッグ用にを変更しました。元の状態に戻す必要があります)

スーパーで何をしようとしていましたか?

于 2011-03-17T11:28:22.417 に答える