I have never handled reverse operators before, so please no flaming! Just finished learning about them so wanted to try them out. But for some reason, it is not working. Here is the code:
>>> 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
If I change __rsub__
to __sub__
, it works.
What am I doing wrong? Also what is the purpose of these reverse operators?
Python reversed() The reversed() method computes the reverse of a given sequence object and returns it in the form of a list.
Strings can be reversed using slicing. To reverse a string, we simply create a slice that starts with the length of the string, and ends at index 0. The slice statement means start at string length, end at position 0, move with the step -1 (or one step backward).
To reverse a string with the list reverse() method, first, the string needs to be converted to a list using the list constructor. Then the list items are reversed in place with the reverse() method, and finally, the list items are joined into a string using the join() method.
The point of these methods is to allow this:
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
Very rarely useful though, usually you just use things of the same type and the direct __sub__
From Python's Data model at http://docs.python.org/reference/datamodel.html :
These methods are called to implement the binary arithmetic operations (+, -, *, /, %, divmod(), pow(), **, <<, >>, &, ^, |) with reflected (swapped) operands. These functions are only called if the left operand does not support the corresponding operation and the operands are of different types. [2] For instance, to evaluate the expression x - y, where y is an instance of a class that has an
__rsub__()
method,y.__rsub__(x)
is called ifx.__sub__(y)
returns NotImplemented.
However - both objects must not be of the same class - that means, that even if you put a __sub__
method returning NotImplemented on your example above, you will still get the same error: Python just assumes your Subtract class can't subtract from "Subtract" iobjects, no matter the order.
However, this works:
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With