flybonzai flybonzai - 17 days ago 4
Python Question

Why is it necessary to return "self" in magic method overloading?

I'm overloading the

__iadd__
magic method for a class, and unless I return self it fails with the error that I can't add
NoneType
and
str
. I can infer from the error that because I'm not returning
self
, the implicitly returned
None
can't be added. I'm performing an in-place change howerver, and so I'm more interested in what's happening under the hood. Here is a sample method that adds lists of dict objects:

class StageChanges(LeverObject):
def __init__(self):
super().__init__('stage_changes')
self.stage_changes = []

def __iadd__(self, other):
self.stage_changes.extend(other)
return self

Answer

Because the documentation says:

These methods [the __i*__ methods] are called to implement the augmented arithmetic assignments (+=, -=, *=, /=, //=, %=, **=, <<=, >>=, &=, ^=, |=). 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).

They don't have to return self, but they do have to return the result, because that result is then assigned back to the target on the left side of the equals sign. In other words, __iadd__(x, y) has to return the result of x+y just like __add__(x, y) has to return the result of x+y. It's just __iadd__ may, in addition mutate the left-hand operand if it wants to.

Or, as you'll no doubt see if you look for other questions about this, x += y is not, as some people think, equivalent to x.__iadd__(y). It is equivalent to x = x.__iadd__(y).

Comments