python - 为什么下面的代码不会抛出错误?

标签 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.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 没有实现。为什么没有报错?

最佳答案

Base 类中 text 属性的 getter 和 setter 都被命名为 text,因此它们只在 中出现一次>__abstractmethods__ 设置。当您覆盖 SubClass 中的 getter 时,它“算”为好像它也覆盖了 setter。

不幸的是,虽然只有 getter 的抽象 property 工作正常,但似乎并没有一种优雅的方式来拥有一个同时具有抽象 getter 和 setter 的属性。如果您使用单个名称,则只需要覆盖该名称(正如您所发现的那样,覆盖不需要 setter )。如果您为这些函数使用单独的名称,然后使用 text = property(_text_get, _text_set),则具体子类将需要替换所有三样东西(getter、setter 和属性对象本身)。更好的方法可能是让属性本身在 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)

编辑:今天阅读文档后(现已弃用)abc.abstractproperty ,我想我更好地理解了为什么只读属性没有错误(它并不像我上面说的那么简单)。

您没有收到错误的原因是您的新属性具有与基类不同的“设置”实现。当然,该行为会引发异常,但从技术上讲,这是一种不同的行为,它会覆盖原始 setter 的行为。

如果您通过使用 @Base.text.getter 作为 SubClass 中覆盖的 setter 函数的装饰器而不是创建新的 来更新旧属性property 完全从头开始,你会得到一个关于抽象方法 text 没有被覆盖的错误。

关于python - 为什么下面的代码不会抛出错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23435259/

相关文章:

django - 如何在 Django Rest Framework 中更改 View 集检索响应?

python - 无法使用 django-python3-ldap 连接到 ldap

python - BigQuery 插入作业而不是流式处理

python - 将 lambda 应用于数据框,但仅限于特定的行数

python - Try, except 子句 with if, else

javafx - 从 getValue() 和 setValue() 函数之外的 Delegated Property 中获取 KProperty 信息

vb.net - 在 Visual Basic 宏中访问 Visual Studio 2010 项目属性

c# - 改进属性(property)监控代码?

python - 如何在python中将数组转换为索引

python - 从 xlsx 文件调用时出现属性错误,但在创建数据框 pandas 时却没有出现属性错误