【问题标题】:Override both getter and setter of a property覆盖属性的 getter 和 setter
【发布时间】:2018-11-08 02:10:17
【问题描述】:

我想同时覆盖子类中属性的 getter 和 setter。考虑以下python3代码sn-p:

class Base():
    @property
    def value(self):
        return "Base.value"

    @value.setter
    def value(self, value):
        pass

class Child(Base):
    @Base.value.getter
    def value(self):
        return "Child.value"

    @Base.value.setter
    def value(self, value):
        pass

c = Child()
print(c.value)

这个程序打印Base.value,这意味着value getter 没有被覆盖。但是,如果我删除 Child 类中的 value setter,程序会打印 Child.value,这意味着 getter 被覆盖。

这种覆盖属性的方式有什么问题?为什么修改 setter 会改变 getter 的行为?以及如何正确覆盖子类中的 getter 和 setter?

【问题讨论】:

标签: python python-3.x


【解决方案1】:

根据我的观察,如果只需要覆盖 setter(或 getter),我认为您应该使用 @Base.value.setter(或 .getter)装饰器。

如果您必须同时覆盖两者,只需使用通常的 @property 方法即可。

class Base():
    def __init__(self):
        self._value = 'Value'

    @property
    def value(self):
        print('Base.Getter')
        return f'Base.{self._value}'

    @value.setter
    def value(self, value):
        print('Base.Setter')
        self._value = value

class Child(Base):
    @property
    #@Base.value.getter
    def value(self):
        print('Child.Getter')
        return f'Child.{self._value}'

    @value.setter
    #@Base.value.setter
    def value(self, value):
        print('Child.Setter')
        self._value = value

b, c = Base(), Child()
print(b.value)
print(c.value)
b.value = 'test.base'
c.value = 'test.child'
print(b.value)
print(c.value)

打印:

Base.Getter
Base.Value
Child.Getter
Child.Value
Base.Setter
Child.Setter
Base.Getter
Base.test.base
Child.Getter
Child.test.child

【讨论】:

  • 谢谢,这行得通。因此,Base.value.getter/setter 装饰器似乎旨在以某种方式使用另一个类的属性,同时重新定义它的一部分,而不是表示继承。所以在我的例子中,setter 定义将用Base getter 和新的setter 覆盖value 属性。奇怪...
猜你喜欢
  • 2021-11-06
  • 2011-03-21
  • 2019-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-11
  • 2011-08-25
相关资源
最近更新 更多