Python 为什么下面的代码没有抛出错误?

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

我正在尝试使用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.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版本,因此无法测试。