【问题标题】:Factoring a class getter in Python在 Python 中分解一个类 getter
【发布时间】:2021-06-12 16:51:33
【问题描述】:

我有一个基本抽象类,其他 2 个类应该从该类继承。这些子类都应该在基类的 getter 属性上实现自己的 setter。不必(多余地)为每个子类重新定义相同的 getter 方法会非常好,但如果他们可以继承 getter 并将自己的 setter 放在上面。这在 Python 中可行吗? 代码如下所示(当然会引发错误!):


class Base:
    def __init__(self):
        self._x = 0
    @property
    def x(self): return self._x
    
class A(Base):
    def __init__(self):
        super().__init__()
    @x.setter
    def x(self, newx): self._x += newx

class B(Base):
    def __init__(self):
        super().__init__()
    @x.setter
    def x(self, newx): self._x -= newx

【问题讨论】:

    标签: python properties getter setter


    【解决方案1】:

    您必须在Base 类的命名空间中引用property,所以以下应该可以工作:

    class Base:
        def __init__(self):
            self._x = 0
        @property
        def x(self): return self._x
    
    class A(Base):
        def __init__(self):
            super().__init__()
        @Base.x.setter
        def x(self, newx): self._x += newx
    
    class B(Base):
        def __init__(self):
            super().__init__()
        @Base.x.setter
        def x(self, newx): self._x -= newx
    

    只是为了演示,在 REPL 中:

    >>> class Base:
    ...     def __init__(self):
    ...         self._x = 0
    ...     @property
    ...     def x(self): return self._x
    ...
    >>> class A(Base):
    ...     def __init__(self):
    ...         super().__init__()
    ...     @Base.x.setter
    ...     def x(self, newx): self._x += newx
    ...
    >>> class B(Base):
    ...     def __init__(self):
    ...         super().__init__()
    ...     @Base.x.setter
    ...     def x(self, newx): self._x -= newx
    ...
    >>> base = Base()
    >>> a = A()
    >>> b = B()
    >>> base.x, a.x, b.x
    (0, 0, 0)
    >>> base.x = 10
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: can't set attribute
    >>> a.x = 10
    >>> b.x = 10
    >>> base.x, a.x, b.x
    (0, 10, -10)
    

    【讨论】:

      【解决方案2】:

      为什么不在基类上定义setter?让它提高NotImplementedError

      我一直更喜欢 x = propertey(getter, setter) 自己语法。

      你会得到

      class Base:
          def __init__(self):
              self._x = 0
          
          def getter(self):
              return self._x
      
          def setter(self):
              raise NotImplementedError
      
          x = property(getter, setter)
      

      现在只需在派生类上编写setter 方法即可。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-01-08
        • 2017-11-22
        • 2011-09-13
        • 1970-01-01
        • 1970-01-01
        • 2018-02-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多