Issue
Is it possible in python to overload operators for a class so that the order of variables in using the operator does not matter?
For example, is there a way to do the following, without getting a TypeError?
class A:
def __init__(self, x: int):
self.x = x
def __add__(self, other: int):
return self.x + other
a = A(1) + 4 # a = 5
# what about this:
a = 4 + A(1)
Solution
This what the __rxxx__
special methods are for. You implement the forward methods to be type strict (expect specific concrete types) (returning NotImplemented
when a recognized type was not provided), and implement the reverse methods to be more liberal (accepting ABC interfaces, because if you're called, you're the last chance to get it right). The __rxxx__
methods pass the left hand side as their second argument so you know which in which direction the computation is being performed.
For your class, a properly written pair of operators would be something like:
import numbers
class A:
def __init__(self, x: int):
self.x = x
def __add__(self, other: int):
if isinstance(other, int):
return self.x + other
if isinstance(other, A):
return type(self)(self.x + other.x)
return NotImplemented
def __radd__(self, other: numbers.Integral):
if isinstance(other, numbers.Integral): # Accept broader ABC rather than just int
return other + self.x
if isinstance(other, A):
return type(self)(other.x + self.x)
return NotImplemented
Implementing each of these in this way when you have a lot of them can get pretty ugly, so frequently you want to refactor to generate the methods using operator
module utilities; you can refer to the source of the fractions.Fraction
class for a more complete/complex example (it was intentionally written to provide such an example to people implementing their own numeric types)
Answered By - ShadowRanger
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.