2016-03-02 131 views
2

当我遇到__rsub__方法时,我在教自己的Python。虽然我可以在官方文档中的方法找到解释:什么是在Python中使用'_rsub__'方法的典型实例?

这些方法称为执行二进制算术运算(+, - ,*,/,//%,divmod(),POW() ,**,< <,>>,&,^,|)与反射(交换)操作数。这些函数仅在左操作数不支持相应操作且操作数具有不同类型时才会调用。 [2]例如,要评估表达式x-y,其中y是具有rsub()方法的类的实例。 rsub(x)如果x被调用。 sub(y)返回NotImplemented。

我不能想象为什么该方法是必要的,它在现实中的使用方式。

您是否愿意给我一个该方法有用的典型环境?

+2

例如你想为你的类型实现一个'-'来处理整数,并且你希望它能够工作,无论int是在左边还是右边,并且你不能改变'-'实现的int –

回答

0

基本示例。你写你自己的int般类:

class FooInt: 
    ... other stuff elided ... 

    def __sub__(self, other): 
     if isinstance(other, FooInt): 
      return self.__class__(self.intvalue - other.intvalue) 
     elif isinstance(other, int): 
      return self.__class__(self.intvalue - other) 
     else: 
      return NotImplemented 

现在你有一些代码的作用:

FooInt(123) - 456 

也能正常工作; Python在左侧看到FooInt,看到它有__sub__,并且调用FooInt.__sub__(FooInt(123), 456),它返回时没有错误,我们很好。

接下来,我们看到:

123 - FooInt(456) 

的Python试图调用int.__sub__(123, FooInt(456)),但int不知道如何处理FooInt,并返回NotImplemented;它不知道intvalue有一个它可以用于这个目的的价值。在这一点上,Python不能仅仅调用FooInt.__sub__(FooInt(456), 123),因为它不能假设减法是可交换的(事实上,在大多数数值系统中,在这种情况下,减法是不可交换的,所以不能只交换右侧和左侧的操作员并获得正确的结果)。这就是为什么__rsub__存在;它可以让你检查其它类的处理操作的装置,同时告诉它两件事情:

  1. 这是对二元运算符的右侧(允许它正确处理可交换)
  2. 该项目上左侧不知道如何处理手术,所以这是最后一次正确的手术。

第二点也很重要。在执行__xxx__(左侧操作符)时,您希望对所识别的类型非常保守。如果你不知道你正在使用一个已知正确的处理程序的已知具体类型,你不应该尝试处理未知的类型;另一种类型可能知道如何正确操作,因此您返回NotImplemented并让对方处理它。当你实施__rxxx__时,你是最后的机会;另一个人不知道该怎么做,所以如果你有任何处理它的方法,你应该对自己接受的事情保持自由,并尽力做到最好。您可以在Implementing the arithmetic operations上的Python文档中看到此操作;所述__xxx__操作检查混凝土类型(Fraction,它检查Fractionintfloat,和complex),而运营商__rxxx__检查一般接口(numbers.Integralnumbers.Rationalnumbers.Real等)。

我已经掩盖了一个比较重要的观点:If the class on the right side is a subclass of the class on the left, it has its reflected __rxxx__ method called first;假定是子类将有更多的信息来正确地确定要做什么,所以它给予了执行操作的第一步。

相关问题