Python mutable and immutable objects
introduction
In Python it's important to know that everything is an object, and that they can be either mutable or immutable.
Since everything in Python is an Object, every variable holds an object instance. When an object is initiated, it is assigned a unique object id. Also, its type is defined at runtime and once set can never change, however its state can be changed if it is mutable. Simple put, a mutable object can be changed after it is created, and an immutable object can’t.
id() and type()
id() is a built-in function (always available) that accepts a single parameter and is used to return the identity of an object.?This identity is unique and constant for this object during its lifetime. Two objects with non-overlapping lifetimes may have the same id() value.
type()?is another built-in function that returns the type of the object passed parameter.
Mutable objects
Mutable objects can be modified (mutated), thair state/contens can be changed during runtime.
The following objects are mutable:
Immutable objects
Immutable objects on the other hand can't be changed during runtime, you must create another one.
The following objects are immutable:
How Python treats mutable and immutable objects
If we execute these assignment statements:
a = "banana"
b = "banana"
we know that?a?and?b?will refer to a string with the letters?"banana". But we don’t know yet whether they point to the?same?string. There are two possible states:
领英推荐
In one case,?a?and?b?refer to two different objects that have the same value. In the second case, they refer to the same object. Thus an object is something a variable can refer to.
We can test whether two names have the same value using?==
>>> a == b
True
We can test whether two names refer to the same object using the?is?operator:
>>> a is b
True
This tells us that both?a?and?b?refer to the same object, int this case that happens because strings are?immutable, Python optimizes resources by making two names that refer to the same string value refer to the same object.
This is not the case with lists:
>>> a = [1, 2, 3]
>>> b = [1, 2, 3]
>>> a == b
True
>>> a is b
False
a?and?b?have the same value but do not refer to the same object.
But that can change with if we create an alias, Since variables refer to objects, if we assign one variable to another, both variables refer to the same object:
>>> a = [1, 2, 3]
>>> b = a
>>> a is b
True
Because the same list has two different names,?a?and?b, we say that it is?aliased. Changes made with one alias affect the other. Although this behavior can be useful, it is sometimes unexpected or undesirable. In general, it is safer to avoid aliasing when you are working with mutable objects. Of course, for immutable objects, there’s no problem.
To get a better understanding, let's see how python handles a list (mutable) expansion vs a tuple (immutable) expansion:
We can see that the list identity is not changed, while the tuple identity is changed. This means that we have?expanded our list, but?created?a completely?new tuple.
Mutable and immutable objects: passing arguments to functions
This also affects the way objects work when passing them as arguments, another example:
The list was passed as an argument to the modify() function, this function mutated the contents of the list, and this mutation is still present in the main program. This is not the case with immutable objects:
Now we passed a tuple as a parameter, the modify() function creates a new tuple with values (1, 2, 3, 4, 5) BUT this new tuple "dies" with the end of the modify() function, the change as we can see is not present in the main program.