Python覆盖没有setter的getter

时间:2013-04-03 11:22:59

标签: python oop properties setter getter

class human(object):
    def __init__(self, name=''):
        self.name = name

    @property
    def name(self):
        return self._name

    @name.setter
    def name(self, value):
        self._name = value

class superhuman(human):
    @property
    def name(self):
        return 'super ' + name

s = superhuman('john')
print s.name

# Doesn't work :( "AttributeError: can't set attribute"
s.name = 'jack'
print s.name

我希望能够覆盖该属性,但能够使用超级父级的setter,而不必覆盖子类中的setter。

这可能是pythonicaly吗?

1 个答案:

答案 0 :(得分:41)

使用 原始属性的.getter装饰器:

class superhuman(human):
    @human.name.getter
    def name(self):
        return 'super ' + self._name

请注意,您必须使用全名来访问父类的原始属性描述符。

演示:

>>> class superhuman(human):
...     @human.name.getter
...     def name(self):
...         return 'super ' + self._name
... 
>>> s = superhuman('john')
>>> print s.name
super john
>>> s.name = 'jack'
>>> print s.name
super jack

property描述符对象只是一个对象,即使它可以有多个与之关联的方法(getter,setter和deleter)。现有.getter描述符提供的.setter.deleterproperty装饰器函数返回描述符本身的副本,并替换了一个特定方法。

因此,在human基类中,您首先使用@property装饰器创建描述符,然后将该描述符替换为同时具有getter和具有@name.setter语法的setter。这是因为python装饰器用相同的名称替换原始的装饰函数,它基本上执行name = name.setter(name)。有关如何运作的详细信息,请参阅How does the @property decorator work?

在您的子类中,您只需使用该技巧创建描述符的新副本,只需更换getter。