【问题标题】:Why are __sub__ and __rsub__ implemented and, in this way, for numbers.Complex为什么要实现 __sub__ 和 __rsub__ 并以这种方式实现 numbers.Complex
【发布时间】:2016-11-08 14:57:20
【问题描述】:

我正在查看numbers 模块中Complex 的实现,并注意到__sub____rsub__s 的实现看起来像这样:

def __sub__(self, other):
    """ self - other """
    return self + -other

def __rsub__(self, other):
    """ other - self """
    return -self + other

这让我很困惑。

首先,我不确定为什么要实现这些(猜测Complex 的所有子类都可以回退到它?)其次,我不明白他们为什么选择使用一元 -像这样的实现。

有什么想法吗?

【问题讨论】:

    标签: python class numbers abstract-base-class


    【解决方案1】:

    这是一个子类可以使用的通用实现,是的,如果他们愿意的话。这是一个额外的目标;这些 ABC 类型的主要目标是能够对数字类型进行回避(参见PEP 3141 – A Type Hierarchy for Numbers

    实现使用一元减号来避免递归;如果你使用了self - other,那么Python 使用self.__sub__(other)self.__rsub__(other)再次

    由于减法可以通过一元减法运算转换为加法,因此 ABC 的作者能够为您提供这些方法作为奖励;另一种方法是提供@abstracmethod 方法,强制子类提供具体的实现。您的子类现在可以可选地以不同的方式实现这些方法,如果这样更有效的话,但他们没有必须这样做。

    这是标准库提供的所有 ABC 中使用的模式。如果您查看documentation for the collections.abc module,您会注意到一个 Mixin Methods 列;这些都是各个 ABC 作为具体实现提供的所有方法,这些实现可能依赖于也可能不依赖于该 ABC 或其基类定义的抽象方法。

    另请参阅构建 PEP 3141 的一般 PEP 3119 – Introducing Abstract Base Classes

    一些 ABC 还提供具体(即非抽象)方法;例如,Iterator 类有一个 __iter__ 方法返回自身,实现了迭代器的一个重要不变量(在 Python 2 中,每个迭代器类必须重新实现)。这些 ABC 可以被视为“混合”类。

    【讨论】:

    • 有道理,我在考虑递归,但我想验证它确实是原因。您对为什么只有__sub____rsub__ 有任何想法吗?也就是说,你能看出像__add__ 这样的笨蛋为什么不这样做的任何原因吗?
    • @user6774416:您不能以仅依赖于已定义的其他方法的方式表达这些方法,因此它们保持抽象。
    • __neg__ 未实现,因此您必须定义它。定义好之后,您可以使用预定义的 __sub__/__rsub__,或提供您自己的(可能更高效)版本。
    猜你喜欢
    • 2023-04-01
    • 1970-01-01
    • 2018-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-05
    • 1970-01-01
    相关资源
    最近更新 更多