Python覆盖没有setter的getter

LuR*_*RsT 26 python oop getter setter properties

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
Run Code Online (Sandbox Code Playgroud)

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

pythonicaly可能吗?

Mar*_*ers 42

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

class superhuman(human):
    @human.name.getter
    def name(self):
        return 'super ' + self._name
Run Code Online (Sandbox Code Playgroud)

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

示范:

>>> 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
Run Code Online (Sandbox Code Playgroud)

property描述对象就是一个对象,尽管它可以有多个与之相关的方法(吸气,setter和删除器).现有描述符提供的.getter,.setter.deleter装饰器函数property返回描述符本身的副本,替换了一个特定方法.

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

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