从子类访问python @property的值

时间:2015-08-07 20:44:28

标签: python python-2.7 properties descriptor

我正在尝试将oauthlib实现重新编写为金字塔应用程序,并在@property装饰类defs上遇到一些默认值的问题。

我以某种方式暴露属性对象,而不是调用/执行它们。

有人能建议一种“执行”这些属性的好方法吗?似乎用任何对象调用fget无效:

self.propertyname.fget(self)

这看起来很尴尬 - 就像这整个问题一样。我似乎正在以错误的方式实施某些事情。

此问题的上下文是尝试从配置字典中加载一些值并回退到基类的属性上。基本形式如下,并且很乐意接受关于更好实施的建议。

class Parent(object):
    @property
    def fieldname(self):
        """returns a tuple"""
        return (1, 10)

class Child(Parent):
    @property
    def fieldname(self):
        """returns a tuple"""
        return self._config.get('fieldname', 
                                Parent.fieldname
                                )

1 个答案:

答案 0 :(得分:3)

property个对象是descriptors,这意味着它们在作为属性访问时会自动绑定到实例(这也是创建方法的方式)。

如果您想访问父property个对象,可以通过调用descriptor.__get__()方法并传入self来手动绑定它:

Parent.fieldname.__get__(self))

property.fget()方法只是原始的未装饰的函数对象。您可以像任何未绑定的方法一样调用它,您可以再次手动传递self

Parent.fieldname.fget(self)

或将其绑定为方法,然后调用:

Parent.fieldname.fget.__get__(self)()

最后但并非最不重要的是,您可以使用super() object为您处理绑定:

super(Child, self).fieldname

找到具有fieldname属性的类层次结构的MRO(方法解析顺序)中的下一个对象,并将其绑定,就像上面的显式示例一样。

就个人而言,我更喜欢super()选项;它是您想要访问原始的,现在被覆盖的属性的最佳文档。

演示:

>>> class Parent(object):
...     @property
...     def fieldname(self):
...         """returns a tuple"""
...         return (1, 10)
... 
>>> class Child(Parent):
...     @property
...     def fieldname(self):
...         """returns a tuple"""
...         return self._config.get(
...             'fieldname', 
...             super(Child, self).fieldname)
... 
>>> child = Child()
>>> child._config = {}
>>> child.fieldname
(1, 10)
>>> child._config['fieldname'] = ('foo', 'bar')
>>> child.fieldname
('foo', 'bar')