0

i wrote the two methods, i still see no difference between the two methods..my class works fine so far , but since the methods are written the same, i still can't understand why when i do : x+1 it calls add , and 1+x it calls radd ?

  def __add__(self,other):
    assert isinstance(other,(Rational,int,str))
    other=Rational(other)
    n = self.n * other.d + self.d * other.n
    d = self.d * other.d
    return Rational(n, d)

def __radd__(self,other):
    assert isinstance(other,(Rational,int,str))
    other=Rational(other)
    n =self.d * other.n + other.d * self.n
    d=other.d * self.d
    return Rational(n, d)

2 Answers2

0

When Python evaluates X+Y, it first calls

X.__add__(Y)

if that returns NotImplemented, then Python calls

Y.__radd__(X)

This example demonstrates when __radd__ versus __add__ is called:

class Commuter:
    def __init__(self,val):
        self.val=val
    def __add__(self,other):
        print 'Commuter add', self.val, other
    def __radd__(self,other):
        print 'Commuter radd', self.val, other

x = Commuter(88)
y = Commuter(99)
x+1
# Commuter add 88 1

1+y
# Commuter radd 99 1

x+y
# Commuter add 88 <__main__.Commuter instance at 0xb7d2cfac>

In this case:

In [3]: (1).__add__(y)
Out[3]: NotImplemented

So y.__radd__(1) gets called.

Community
  • 1
  • 1
unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
  • when i run my class without __radd__it won't give me , but when i do run it ,it allows me to run it normally,so i guess it means this is alright? def __add__(self,other): assert isinstance(other,(Rational,int,str)) other=Rational(other) n = self.n * other.d + self.d * other.n d = self.d * other.d return Rational(n, d) def __radd__(self,other): assert isinstance(other,(Rational,int,str)) other=Rational(other) n =self.d * other.n + other.d * self.n d=other.d * self.d return Rational(n, d) – user3025851 Dec 04 '13 at 20:58
  • I'm not sure what your question is, and it's really hard to read code in the comments. Please edit your original question, add the code there, using the `{}` button so the code gets formatted properly. – unutbu Dec 04 '13 at 21:05
  • You are defining `__add__` and `__radd__` for the class `Rational`. `x` is an instance of `Rational`, but `1` is not. `1` is an `int`. The `int` class has its own `__add__` and `__radd__` methods. `1+x` causes `(1).__add__(x)` to be called. That returns `NotImplemented`, which causes `x.__radd__(1)` to be called. (By the way, since your `__add__` and `__radd__` methods are identical, you can just say `__radd__ = __add__` instead of defining `__radd__` with `def __radd__(self, other):` ....) – unutbu Dec 04 '13 at 22:49
  • im having a slight problem, lets say im using __add__ , and i add a rational number to a rational number it doesn't work, if its int , then all is well..as for __sub__ its the other way round, it works well when its Rational - Rational, but when its Rational - int, it doesn't work..what might be the problem? – user3025851 Dec 05 '13 at 18:37
0

Given the expression a + b, if object a implements __add__ it will be called with b:

a.__add__(b)

However, if a does not implement __add__ and b implements __radd__ (read as "right-add"), then b.__radd__ will be called with a:

b.__radd__(a)

The documentation explaining this is here.

Carl Groner
  • 4,149
  • 1
  • 19
  • 20