Python 为什么下面的代码没有抛出错误?
我正在尝试使用Python 3编写一个抽象类,如下所示:Python 为什么下面的代码没有抛出错误?,python,python-3.x,properties,abstract-methods,Python,Python 3.x,Properties,Abstract Methods,我正在尝试使用Python 3编写一个抽象类,如下所示: from abc import * class Base(metaclass=ABCMeta): @abstractmethod def __init__(self, text=''): self._text = text @property @abstractmethod def text(self): return self._text @text
from abc import *
class Base(metaclass=ABCMeta):
@abstractmethod
def __init__(self, text=''):
self._text = text
@property
@abstractmethod
def text(self):
return self._text
@text.setter
@abstractmethod
def text(self, text):
self._text = text
class SubClass(Base):
def __init__(self, text):
super().__init__(text)
@property
def text(self):
return super().text
q = SubClass("Test")
当我运行文件时,解释器不会抱怨text.setter没有实现。为什么没有错误?您的
基类中文本属性的getter和setter都命名为文本,因此它们在抽象方法集中只出现一次。当您重写子类中的getter时,它“计数”就好像它也重写了setter一样
不幸的是,虽然只使用getter的抽象属性
可以很好地工作,但似乎并没有一种优雅的方法可以同时使用抽象getter和setter属性。如果使用单个名称,则只需要重写该名称(并且正如您所发现的,重写不需要有setter)。如果为这些函数使用单独的名称,然后使用text=property(\u text\u get,\u text\u set)
,则具体的子类将需要替换所有三个对象(getter、setter和property对象本身)。更好的方法可能是让属性本身在Base
类中具体化,但让它调用抽象getter和setter实现函数,这些函数可以是抽象的,哪些子类可以轻松重写:
@abstractmethod
def _text_get_imp(self):
return self._text
@abstractmethod
_text_set_imp(self, value):
self._text = value
@property
def text(self):
return self._text_get_imp()
@text.setter
def text(self, value)
self._text_set_imp(value)
编辑:在今天阅读了(现在已弃用)的文档之后,我想我更好地理解了为什么只读属性没有错误(它不像我上面说的那么简单)
没有出现错误的原因是,新属性的“设置”实现与基类不同。当然,这种行为会引发异常,但从技术上讲,这是一种不同的行为,它会覆盖原始setter的行为
如果使用@Base.text.getter
作为子类
中重写的setter函数的装饰器,而不是完全从头创建新的属性,从而更新了旧属性
,您将得到一个关于未被覆盖的抽象方法text
的错误。这是Python 3的哪个特定版本?您不是在text.setter的抽象声明中提供了一个带有self的基本实现吗?如果子类不重写抽象类,抽象类的继承将为子类提供基本实现,至少在大多数OO语言中是如此。@user2357112它是Python 3。4@RyanJ:通常,所有带有abstractmethod
的内容都需要重写以实例化类。例如,即使在\uuu init\uuuu
的抽象方法
装饰器下有一个实函数,它仍然需要被重写。啊,是的。我浏览了abc库的python文档,事实上就是这样。我没有那么新的python版本,因此无法测试。