关于oop:python重写不带setter的getter

Python overriding getter without setter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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。

那是不是可能的?


仅使用原房地产的.getter装饰:

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

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

论证:

1
2
3
4
5
6
7
8
9
10
11
>>> 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)。现有property描述符提供的.getter.setter.deleter修饰函数返回描述符本身的副本,替换了一种特定的方法。

所以在你的human基类中,你首先用@property修饰器创建描述符,然后用一个既有getter又有setter的@name.setter语法替换这个描述符。这是因为python修饰符用相同的名称替换了原来的修饰函数,所以它基本上执行name = name.setter(name)。看看@property decorator是如何工作的?关于这一切如何运作的细节。

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