从子类访问 python @属性 的值

accessing value of a python @property from a subclass

我正在尝试将 oauthlib 实现改写为金字塔应用程序,并 运行 改写 @property decorated class defs 上一些默认值的问题。

我以某种方式暴露了 属性 对象,而不是 calling/executing 它们。

任何人都可以建议 'execute' 这些属性的好方法吗?似乎用任何 object/None 调用 fget 都有效:

self.propertyname.fget(self)

虽然这看起来很尴尬——整个问题也是如此。我似乎以错误的方式实施了某些事情。

这个问题的背景是试图从配置字典中加载一些值并返回到基础 class 的 属性。基本形式如下,如有更好的实现建议,欢迎采纳。

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
                                )

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

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

就我个人而言,我更喜欢 super() 选项; it best documents that you want to access the original, now overridden 属性.

演示:

>>> 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')