在Python中使用反向运算符

时间:2010-09-21 19:21:53

标签: python operators

我以前从未处理过反向操作员,所以请不要燃烧!刚刚完成了解它们,所以想尝试一下。但由于某种原因,它不起作用。这是代码:

>>> class Subtract(object):
    def __init__(self, number):
        self.number = number
    def __rsub__(self, other):
        return self.number - other.number


>>> x = Subtract(5)
>>> y = Subtract(10)
>>> x - y         # FAILS!

Traceback (most recent call last):
  File "<pyshell#8>", line 1, in <module>
    x - y
TypeError: unsupported operand type(s) for -: 'Subtract' and 'Subtract'
>>> x.__rsub__(y) # WORKS!
-5

如果我将__rsub__更改为__sub__,则可以。

我做错了什么?这些反向运营商的目的是什么?

4 个答案:

答案 0 :(得分:4)

仅当操作数具有不同类型时才会调用

__rsub__();当它们属于同一类型时,假设如果__sub__不存在则不能减去它们。

另请注意,无论如何你的逻辑都是颠倒过来的;你正在回归自我 - 而不是其他 - 自我

答案 1 :(得分:3)

来自http://docs.python.org/reference/datamodel.html的Python数据模型:

  

调用这些方法来实现   二进制算术运算(+,   带有反射(交换)操作数的 - ,*,/,%,divmod(),pow(),**,&lt;&lt;,&gt;&gt;,&amp;,^,|)。这些功能只是   如果左操作数没有调用   支持相应的操作   和操作数是不同的   类型。 [2]例如,要评估   表达式x - y,其中y是   具有一个类的类的实例   如果__rsub__()返回,则会调用y.__rsub__(x)方法x.__sub__(y)   NotImplemented。

但是 - 两个对象不能属于同一个类 - 这意味着,即使你在上面的例子中放置了一个返回NotImplemented的__sub__方法,你仍然会得到同样的错误:Python只假设你的Subtract无论顺序如何,class都不能从“Subtract”iobjects中减去。

然而,这有效:

class Sub1(object):
    number = 5
    def __sub__(self, other):
        return NotImplemented

class Sub2(object):
    number = 2
    def __rsub__(self, other):
        return other.number - self.number


a = Sub1()
b = Sub2()

print a - b

答案 2 :(得分:3)

这些方法的要点是允许这样做:

class MyNumber(object):
    def __init__(self, x):
        self.x = x

print 10 - MyNumber(9) # fails because 10.__sub__(MyNumber(9)) is unknown

class MyFixedNumber(MyNumber):
    def __rsub__(self, other):
        return MyNumber( other - self.x )

print 10 - MyFixedNumber(9) # MyFixedNumber(9).__rsub__(10) is defined

虽然很少有用,但通常你只使用相同类型和直接__sub__

的东西

答案 3 :(得分:2)

提供了methods with reflected operands,以便当左操作数是基元或不受您控制的其他操作时,您的类可以实现操作符:

  

仅当左操作数不支持相应操作且操作数类型不同时才调用这些函数。

由于它们属于同一类型,因此它是懦弱的拒绝,你应该实现__sub__方法。