Why does calling Python's 'magic method' not do type conversion like it would for the corresponding operator? Why does calling Python's 'magic method' not do type conversion like it would for the corresponding operator? python python

Why does calling Python's 'magic method' not do type conversion like it would for the corresponding operator?


a - b isn't just a.__sub__(b). It also tries b.__rsub__(a) if a can't handle the operation, and in the 1 - 2. case, it's the float's __rsub__ that handles the operation.

>>> (2.).__rsub__(1)-1.0

You ran a.__rsub__(2.), but that's the wrong __rsub__. You need the right-side operand's __rsub__, not the left-side operand.


There is no implicit type conversion built into the subtraction operator. float.__rsub__ has to handle ints manually. If you want type conversion in your own operator implementations, you'll have to handle that manually too.


@user2357112 already said it well but there's nothing like an example.

class A:   def __sub__(self, other):       print('A.__sub__')       if not isinstance(other, A):           return NotImplemented       return 0   def __rsub__(self, other):       print('A.__rsub__')       if not isinstance(other, A):           return NotImplemented       return 0class B:   def __sub__(self, other):       print('B.__sub__')       if not isinstance(other, B):           return NotImplemented       return 0

a1 = A()a2 = A()b = B()a1 - a2A.__sub__# 0

Objects a1 and a2 are compatible (both type A), a valid result is returned.

Next, consider,

b - a1B.__sub__A.__rsub__# TypeError: unsupported operand type(s) for -: 'B' and 'A'

Objects b and a1 are not compatible. First, b.__sub__ is tried, which returns NotImplemented, so a1.__rsub__ is tried, which also returns NotImplemented. So a TypeError is raised.

Finally,

a1 - bA.__sub__# TypeError: unsupported operand type(s) for -: 'A' and 'B'

This time, a1.__sub__ is tried first, which returns NotImplemented. Now, since b.__rsub__ is not defined, a TypeError is raised.