What happens under the hood when we do a += b?
In Python Standard Library we have a module named
operator which contains the functions corresponding to the operator we use to perform object comparisons, logical operations, mathematical operations and sequence operations. And when we use a operator in a statement, a function corresponding to that operator is called.
These operators like +=, -=, /= are called Inplace operators.
operator.add(x, y) is equivallent to the expression
x + y.
In the same way when we call
a += b this will call a function
operator.iadd(a, b). Many of the functions in
operator module have variant with the double underscore kept, because of backward compatibility. And in case, if __iadd__ is not present __add__ or __radd__ will be called.
And we can also have our own __iadd__ special method:
So now coming to the question, here
a+=, you can understand that it totally depends on the object a, what is implemented in __iadd__ special method and if it is not present then call for __add__ or __radd__ . Method __iadd__ works same as list extend method does.
As a concrete example:
In first example since b and a reference to the same object and because of in-place operator it just extend that existing list and you can see that
id(b) remained same after the action performed, because lists are mutable. But in second example it concatenate the new list with the list b is referencing to, and store the concatenated list in
+=tries to call the __iadd__ special method, and if that isn’t available it tries to use __add__ instead. So the issue is with the difference between these special methods.
- The __iadd__ special method is for an in-place addition, that is it mutates the object that it acts on. The __add__ special method returns a new object after performing the addition.
Reference for better understanding of in-place operators: https://docs.python.org/3/library/operator.html#inplace-operators