【问题标题】:Access superclass' property setter in subclass在子类中访问超类的属性设置器
【发布时间】:2017-08-03 10:45:51
【问题描述】:

我有一个 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 一样这样做,但这在这里并不完全适用,因为我实际上并不想在 B 中定义一个新的 setter,只需重新使用 A 中的那个。
有没有人提示如何解决这个问题?可能是微不足道的,但我现在没有看到它:/

【问题讨论】:

  • 我突然想到我可以像这样添加一个显式的 getter 方法,并让 mode 属性调用这个 getter `return self._mode_getter(),然后覆盖 _mode_getter()。这应该可以,但添加了一个可能不需要的方法

标签: python inheritance properties overriding


【解决方案1】:

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 委托给该方法,就像您为 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

【讨论】:

    【解决方案2】:

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

    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。

    【讨论】:

      【解决方案3】:

      这样对我有用

      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
      

      【讨论】:

        猜你喜欢
        • 2013-03-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-01-30
        • 2021-03-13
        • 2013-12-12
        • 1970-01-01
        • 2023-01-24
        相关资源
        最近更新 更多