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__调试,它应该改回你的样子)

你想用 super 做什么?

于 2011-03-17T11:28:22.417 回答