Подтвердить что ты не робот

Переопределение наследственных свойств getters и seters в Python

В настоящее время я использую декоратор @property для достижения "геттеров и сеттеров" в нескольких моих классах. Я хочу унаследовать эти методы @property в дочернем классе.

У меня есть код Python (в частности, Im работает в py3k), который выглядит нечетко так:

class A:
    @property
    def attr(self):
        try:
            return self._attr
        except AttributeError:
            return ''

class B(A):
    @property
    def attr(self):
        return A.attr   # The bit that doesn't work.

    @attr.setter
    def attr(self, value):
        self._attr = value

if __name__ == '__main__':
    b = B()
    print('Before set:', repr(b.attr))
    b.attr = 'abc'
    print(' After set:', repr(b.attr))

Я отметил часть, которая не работает с комментарием. Я хочу, чтобы getter gett базового класса возвращался. A.attr возвращает объект свойства (который, вероятно, очень близок к тому, что мне нужно!).

Edit:
Получив ответ от Неда, я придумал, что я считаю более элегантным решением этой проблемы.

class A:
    @property
    def attr(self):
        try:
            return self._attr
        except AttributeError:
            return ''

class B(A):        
    @A.attr.setter
    def attr(self, value):
        self._attr = value

if __name__ == '__main__':
    b = B()
    print('Before set:', repr(b.attr))
    b.attr = 'abc'
    print(' After set:', repr(b.attr))

Декоратор .setter ожидает объект свойства, который мы можем использовать с помощью @A.attr. Это означает, что нам не нужно объявлять свойство снова в дочернем классе.

(В этом разница между работой над проблемой в конце дня и работой над ней в начале дня!)

4b9b3361

Ответ 1

Я думаю, вы хотите:

class B(A):
    @property
    def attr(self):
        return super(B, self).attr

Вы упомянули о желании вернуть родительский класс getter, но вам нужно вызвать getter, а не вернуть его.

Ответ 2

Чтобы переопределить сеттер в python 2, я сделал следующее:

class A(object):
    def __init__(self):
        self._attr = None

    @property
    def attr(self):
        return self._attr

    @attr.setter
    def attr(self, value):
        self._attr = value


class B(A):
    @A.attr.setter
    def attr(self, value):
        # Do some crazy stuff with `value`
        value = value[0:3]
        A.attr.fset(self, value)