Mutating without mutating

Even operations which seem naturally mutating in nature are not necessarily so. Consider the augmented assignment operator:

>>> t = 5
>>> id(t)
4297261280
>>> t += 2
>>> id(t)
4297261344

At first glance, it appears that we're asking Python to increment the integer value t by two. But the id() results here clearly show that t refers to two different objects before and after the augmented assignment.

Rather than modifying integer objects, here's a depiction of what's actually happening. Initially, we have the name t referring to an int(5) object:

Figure 4.5: 'x' refers to the integer 5

Next, to perform the augmented assignment of 2 to t, Python create an int(2) object behind the scenes. Note that we never have a named reference to this object; it's managed completely by Python on our behalf:

Figure 4.6: Python creates an integer 2 behind the scenes

Python then performs the addition operation between t and the anonymous int(2) giving us — you guessed it! — another integer object, this time an int(7):


Figure 4.7: Python creates a new integer as the result of the addition

Finally, Python's augmented assignment operator simply reassigns the name t to
the new int(7) object, leaving the other integer objects to be handled by the garbage collector:

Figure 4.8:  Python reassigned the name 't' to the result of the addition