python 2.6 : How to access base class descriptor field hidden by derived class?

标签 python super descriptor

我有一个描述符将数据存储在宿主对象的字典中。 我在类层次结构中有这个描述符的同名字段:

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'

为什么 get 有效而 analogue set 无效? 我可以用比 A.dict['f'].set(b,'a') 更优雅的方式设置 A 的 f 吗?


更正:

在我最初的帖子中给出的表格中,A.f 评估为 A 的以键名命名的属性(缺失)或默认 8192 - 与它无关。这就是为什么我使用 A.dict['f'] - 来排除 get 调用。 需要稍作修改才能将 A.f 评估为所需的 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 提供的属性解决方案不适合我的需求 - 我需要将所有描述符包装在属性中。

最佳答案

如果 A.__dict__['f'].__set__(b,'a') 有效,A.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 做什么?

关于 python 2.6 : How to access base class descriptor field hidden by derived class?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5336147/

相关文章:

python 子进程更新它的行 (\r) - 我需要每次更新

java - 当切入点在父类(super class)上但派生类覆盖时,如何避免两次击中切入点?

python - "useless super delegation"的 Pylint 警告

python - 当直接从 `object` 继承时,我应该调用 super().__init__() 吗?

PointCloud 库中的 C++ : No matching function to call to

python - 如何从 paramiko 的标准输出中删除坏字符

python - 在共享主机上访问 Django Runserver

python 在继续之前等待第n位数字

python - 异步设置python3.5中的描述符

python - 类属性无故改变值