文件
Python文档(版本3.8):
上面的示例定义了一个只读属性;你也可以通过适当地将一个或多个底层方法标记为抽象来定义读写抽象属性:
class C(ABC):
@property
def x(self):
...
@x.setter
@abstractmethod
def x(self, val):
...
如果只有一些组件是抽象的,那么只有那些组件需要更新以在子类中创建具体属性:
我的代码
from abc import ABC, abstractmethod
class C(ABC):
@property
def x(self):
...
@x.setter
@abstractmethod
def x(self, val):
...
class D(C):
@property
def x(self):
pass
d = D()
- 预期行为**:示例化失败,因为存在未定义的抽象方法
- 实际行为**:示例化而不出错
问题
为什么这个示例化不会失败?如果在派生类中没有实现setter,我如何编写它,使它示例化失败?文档似乎表明这应该是abstractmethod
的一个涵盖的用例。文档还提供了一个示例,其中getter和setter都是抽象方法,这正是我的目标。
参考:www.example.comhttps://docs.python.org/3.8/library/abc.html#abc.abstractproperty
1条答案
按热度按时间2jcobegt1#
从根本上说,问题在于getter和setter只是同一个类属性的一部分,在
@property
x
中,你有一个fget
,fset
和fdel
,它们组成了getter,setter和deleter(不一定都设置了),它们可能是抽象的,阻止了init,或者根本不存在。在你的
class D
中,你创建了一个新的@property
,它完全覆盖了父@property
,所以不再有任何抽象的setter来阻止初始化这个类。输出:
所以,如果你想重写getter,你需要使用
@C.x.getter
来明确它:输出:
这样就不用重写整个
property
,只需要重写它的特定函数。我不会把制造新的
properties
和覆盖父对象混合在一起,我在测试中看到了这种挑剔的行为:输出:
重新排序的类定义:
输出: