Can __radd__ work with the operands in any order?

2019-08-12 05:53发布

问题:

I want my Fraction class to work as a float when it's being added to floats or integers so I can naturally perform operations with it, but it's only working when the Fraction is the rightmost operand. Is there a way to make it work with the operands in any order or should I override another method that I haven't learned of?

Code (I guess variable names are pretty self-explanatory):

def __radd__(self,target):
    if type(target) == int or type(target) == float:
        return target + self.num/self.den

1 + Fraction(1,2) returns 1.5 as it should but Fraction(1,2) + 1 raises:

Traceback (most recent call last):
  File "/Users/mac/Desktop/programming/python/fraction.py", line 86, in <module>
    print(my_fraction + 1)
  File "/Users/mac/Desktop/programming/python/fraction.py", line 28, in __add__
    new_den = self.den * target.den
AttributeError: 'int' object has no attribute 'den'

回答1:

The __radd__ special method only applies to when you do value + self. If you want to handle self + value, you need to overload the __add__ special method.

Since they both do the same thing, you can just do:

def __add__(self, target):
    if isinstance(target, (int, float)):
        return target + self.num/self.den
__radd__ = __add__

An easy way to remember this is to treat the r in __radd__ as standing for "right". So, you use __radd__ when your class is on the right of the + operator.

Also, you'll notice that I used isinstance to do the typechecking. Aside from being cleaner, this way is preferred by most Python programmers and is explicitly advocated in PEP 0008.