Python Magic Method Augmented Assignment Misunderstanding
Solution 1:
About __iadd__ (and other __iXXX__ methods):
These methods should attempt to do the operation in-place (modifying self) and return the result (which could be, but does not have to be, self).
Your __iadd__ method doesn't "assigns a nonetype to self.angle", it returns None (default value when a function has no explicit return), and this rebinds your current name to None, ie:
classFoo(object):
def__init__(self, angle=120):
self.angle = angle
def__add__(self, other):
"""Check for recursion, then return the added value."""print"Foo.add"
val = self.angle + other
while val > 360:
val -= 360while val < 0:
val += 360return val
def__iadd__(self, other):
"""Augmented addition assignment."""print"Foo.iadd"
val = self.__add__(other)
self.angle = val
f = Foo()
f += 20print f isNoneTo make a long story short : you want __iadd__ to return something meaningfull, most probably self.
Solution 2:
Both __add__ and __iadd__ should return an Angle object:
classAngle(object):def__init__(self, angle):
self.angle = angle % 360def__add__(self, other):
return Angle(self.angle + other.angle)
def__iadd__(self, other):
returnself.__add__(other)
Note use of angle % 360 to keep angle in range(0, 360).
Solution 3:
Just delete your __iadd__ method completely.
This will make += operator fall back onto __add__, which is the preferred behaviour for objects which model immutable types.
Example:
classAngle(int):def__init__(self, val):
self.val = val % 360def__add__(self, other):
return Angle(self.val + other)
def__sub__(self, other):
return Angle(self.val - other)
def__neg__(self):
return Angle(-self.val)
def__repr__(self):
# just for demonstration purposes okreturn str(self.val)
Let's try it out...
>>>a = Angle(35)>>>a
35
>>>a + 400
75
>>>a
35
>>>a += 400>>>a
75
>>>a - 75
0
>>>a - 76
359
>>>a
75
>>>a -= 76>>>a
359
No __iadd__ or __radd__ is needed, let python handle the magic for you.
Solution 4:
You need to return self from the implementation of __iadd__ since the return value of __iadd__ is assigned to the left hand side of the += operator. This is what the Python documentation says about the implementation of in-place operators:
These methods should attempt to do the operation in-place (modifying self) and return the result (which could be, but does not have to be, self).
(source)
Post a Comment for "Python Magic Method Augmented Assignment Misunderstanding"