在子类中访问超类的属性设置器

Ema*_* Ey 6 python inheritance overriding properties

我有一个 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'
Run Code Online (Sandbox Code Playgroud)

这引发了

obj.mode = 'test'
AttributeError: can't set attribute
Run Code Online (Sandbox Code Playgroud)

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

bru*_*ers 7

getter 和 setter 存储为property对象的属性(分别作为.fgetand .fset),因此一旦您在子类中重载该属性,您就最明确地提供了 getter 和 setter,即:

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

    @mode.setter
    def mode(self, value):
        self._mode = value
Run Code Online (Sandbox Code Playgroud)

因此,如果您想让 getter 和/或 setter 可重载而不必重新声明属性,则必须定义一个_get_mode方法并使您的属性的 getter 委托给该方法,就像对 setter 所做的那样。

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