views:

93

answers:

3

Hi all. I'm new to Python so apologies in advance if this is a stupid question.

For an assignment I need to overload augmented arithmetic assignments(+=, -=, /=, =, *=, %=) for a class myInt. I checked the Python documentation and this is what I came up with:

def __iadd__(self, other):

    if isinstance(other, myInt):
        self.a += other.a
    elif type(other) == int:
        self.a += other
    else:
        raise Exception("invalid argument")

self.a and other.a refer to the int stored in each class instance. I tried testing this out as follows, but each time I get 'None' instead of the expected value 5:

c = myInt(2)
b = myInt(3)
c += b
print c

Can anyone tell me why this is happening? Thanks in advance.

+11  A: 

You need to add return self to your method. Explanation:

The semantics of a += b, when type(a) has a special method __iadd__, are defined to be:

  a = a.__iadd__(b)

so if __iadd__ returns something different than self, that's what will be bound to name a after the operation. By missing a return statement, the method you posted is equivalent to one with return None.

Alex Martelli
Alex,I always love your answers!
Srinivas Reddy Thatiparthy
@Srinivas, thanks!
Alex Martelli
Thanks for the clear explanation!
Alice
@Alice, you're welcome!
Alex Martelli
+1  A: 

Yes, you need "return self", it will look like this:

def __iadd__(self, other):
    if isinstance(other, myInt):
        self.a += other.a
        return self
    elif type(other) == int:
        self.a += other
        return self
    else:
        raise Exception("invalid argument")
woo
Also, you should make your `Exception` a `TypeError`.
jcdyer
+5  A: 

Augmented operators in Python have to return the final value to be assigned to the name they are called on, usually (and in your case) self. Like all Python methods, missing a return statement implies returning None.

Also,

  • Never ever ever raise Exception, which is impossible to catch sanely. The code to do so would have to say except Exception, which will catch all exceptions. In this case you want ValueError or TypeError.
  • Don't typecheck with type(foo) == SomeType. In this (and virtually all) cases, isinstance works better or at least the same.
  • Whenever you make your own type, like myInt, you should name it with capital letters so people can recognize it as a class name.
Mike Graham