I want to create a class that wraps an int
and allows some things not normally allowed with int
types. Here is my code:
class tInt(int):
def __add__(self, other):
if type(other) == str:
return str(self) + str(other)
elif type(other) == int:
return int(self) + other
elif type(other) == float:
return float(self) + float(other)
else:
return self + other
a = tInt(2)
print (a + "5")
print ("5" + a)
The output was.
>> 25
Traceback (most recent call last):
File "C:\example.py", line 14, in <module>
print ("5" + a)
TypeError: Can't convert 'tInt' object to str implicitly
So, the first print statement ran nicely, and gave what I expected, but the second one gave an error. I think this is because the first one is using tInt's add function because a appeared before + "5" and the second one used the string "5"'s add function first because it appeared first. I know this but I don't really know how to either force a's add function or allow the tInt class to be represented as a string/int/etc.. when a normal type appears before it in an operation.
You need to implement an __radd__
method to handle the case when an instance of your class is on the right hand side of the addition.
The docs say:
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. For instance, to evaluate the expression
x - y
, wherey
is an instance of a class that has an__rsub__()
method,y.__rsub__(x)
is called ifx.__sub__(y)
returnsNotImplemented
.
Example:
class tInt(int):
def __add__(self, other):
if isinstance(other, str):
return str(self) + str(other)
elif isinstance(other, int):
return int(self) + other
elif isinstance(other, float):
return float(self) + float(other)
else:
return NotImplemented
def __radd__(self, other):
return self.__add__(other)
a = tInt(2)
for x in ["5", 5, 5.0]:
print (a + x)
print (x + a)
25
25
7
7
7.0
7.0
As @chepner pointed out in the comments, returning NotImplemented for cases that your method doesn't handle will cause Python to try other ways of performing the operation, or raise a TypeError if there is no way to perform the requested operation.
In the above code, the implementation of __radd__
is trivial because integer addition is associative, that is
2 + 3 == 3 + 2
Addition of other types may not be associative, in which case __radd__
will need to do more than just delegate to __add__
:
'a' + 'b' != 'b' + 'a'
[0, 1] + [2, 3] != [2, 3] + [0, 1]
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