在Python中使用反向运算符
我之前从来没有处理过反向运算符。刚学完这个知识,想试试,但不知道为什么不管用。这里是我的代码:
>>> 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 个回答
4
来自Python的数据模型,详细信息可以查看这个链接:http://docs.python.org/reference/datamodel.html:
这些方法是用来实现一些基本的数学运算,比如加、减、乘、除、取余等操作。当你用不同类型的对象进行运算时,如果左边的对象不支持这个操作,就会调用这些方法。举个例子,如果你想计算表达式 x - y,而 y 是一个有
__rsub__()
方法的类的实例,那么如果x.__sub__(y)
返回 NotImplemented,Python 就会调用y.__rsub__(x)
来进行计算。
不过,有一点要注意:这两个对象不能是同一个类的实例。也就是说,即使你在上面的例子中定义了一个 __sub__
方法并返回 NotImplemented,你仍然会遇到同样的错误。Python 会认为你的 Subtract 类无法从 "Subtract" 对象中进行减法,无论顺序如何。
但是,这样做是可以的:
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
6
__rsub__()
这个方法只有在两个操作数类型不同时才会被调用;如果它们类型相同,就会假设如果没有 __sub__
这个方法,那它们是不能相减的。
另外要注意的是,你的逻辑是反的;你返回的是 self - other,而不是 other - self。
6
这些方法的目的是为了让你可以做到这一点:
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__
方法就可以了。