Переопределение методов получения и установки наследуемых свойств в Python - PullRequest
28 голосов
/ 26 июля 2010

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

У меня есть некоторый код Python (в частности, я работаю в 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))

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

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

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.Это означает, что нам не нужно снова объявлять свойство в дочернем классе.

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

Ответы [ 2 ]

28 голосов
/ 18 февраля 2012

Чтобы переопределить установщик в 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)

Чтобы понять, откуда взялся A.attr.fset, смотрите документацию по классу property: https://docs.python.org/2/library/functions.html#property

5 голосов
/ 26 июля 2010

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...