访问子类中的超类'属性setter

时间:2017-03-13 12:07:59

标签: python inheritance properties override

我有一个SuperClass,它定义了一个属性,它是setter,就像这样:

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

    @property
    def mode(self):
        # to be overriden in subclass to implement the actual getter code
        raise NotImplementedError

    @mode.setter
    def mode(self, value):
        # common assertions and input validations
        self._set_mode(value)

    def _set_mode(self, value):
        # to be overriden in subclass to implement the actual setter code
        raise NotImplementedError


class B(A):
    @property
    def mode(self):
        return self._mode

    def _set_mode(self, value):
        self._mode = value


obj = B()
obj.mode = 'test'

哪个提出

obj.mode = 'test'
AttributeError: can't set attribute

似乎我必须在B中注册一个setter。我通常会像@A.mode.setter那样执行此操作,但这并不适用于此,因为我实际上并不想在其中定义新的setter B,只需重复使用A.中的那个 有没有人提示如何解决这个问题?可能是微不足道的,但我现在没有看到它:/

3 个答案:

答案 0 :(得分:4)

getter和setter存储为property对象的属性(分别为.fget.fset),因此只要重载子类中的属性,就最明显地同时提供getter和setter,即:

class B(A):
    @property
    def mode(self):
        return self._mode

    @mode.setter
    def mode(self, value):
        self._mode = value

因此,如果你想让getter和/或setter重载而不必重新声明属性,你必须定义一个_get_mode方法并使你的属性的getter委托给这个方法,就像你为二传手做了。

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

    @property
    def mode(self):
        return self._get_mode()

    def _get_mode(self):
        # to be overriden in subclass to implement the actual getter code
        raise NotImplementedError

    @mode.setter
    def mode(self, value):
        # common assertions and input validations
        self._set_mode(value)

    def _set_mode(self, value):
        # to be overriden in subclass to implement the actual setter code
        raise NotImplementedError


class B(A):

    def _get_mode(self):
        return self._mode

    def _set_mode(self, value):
        self._mode = value

答案 1 :(得分:1)

类似于在 mode.setter 的定义中使用 A,相关问题的 this answer 建议使用基类的属性来定义子类的属性,如下所示:< /p>

class B(A):
    @A.mode.getter              # only this line is changed!
    def mode(self):
        return self._mode

    def _set_mode(self, value):
        self._mode = value

此处,mode.setter 将与 A 相同,但我们替换了 getter。

答案 2 :(得分:0)

这种方式对我有用

class A:
    @property
    def mode(self):
        raise NotImplemented
    
    @mode.setter
    def mode(self, value):
        raise NotImplemented

class B(A):
    @A.mode.setter
    def mode(self, value):
        # your setter implement here