我正在查看numbers
模块中Complex
的实现,并注意到__sub__
和__rsub__
的实现看起来像这样:
def __sub__(self, other):
""" self - other """
return self + -other
def __rsub__(self, other):
""" other - self """
return -self + other
这让我很困惑。
首先,我真的不确定为什么要实现这些(猜测Complex
的所有子类都可以回落到它?),其次,我不能理解为什么他们选择使用这样的一元-
来实现它。
任何想法?
这是一个子类可以使用的通用实现,是的,如果他们愿意的话。这是一个额外的目标;这些ABC类型的主要目标是能够对数字类型进行duck-type(参见PEP 3141 - 数字的类型层次)。
实现使用一元减号来避免递归;如果您使用self - other
,那么Python将再次使用self.__sub__(other)
或self.__rsub__(other)
。
因为减法可以通过一元减法操作转换为加法,所以ABC的作者能够为您提供这些方法作为奖励;另一种选择是提供@abstracmethod
方法,迫使子类提供具体的实现。你的子类现在可以,可选地,以一种不同的方式实现这些方法,如果这是更有效的,但他们没有。
这是标准库提供的所有abc中使用的模式。如果你看一下collections.abc
模块的文档,你会注意到一个Mixin Methods列;
参见通用PEP 3119 - 引入抽象基类, PEP 3141是在这些基类之上构建的:
一些abc还提供具体的(即非抽象的)方法;例如,
Iterator
类有一个返回自身的__iter__
方法,实现了迭代器的一个重要不变式(在Python 2中,每个迭代器类都必须重新实现它)。这些abc可以被认为是"混合"类。