Python3: Mutable, Immutable... everything is object!
Cesar Molina
Software Developer Junior | JavaScript | React JS | HTML | CSS | Figma | Wordpress
Mutable, Immutable… everything is an object!
Python is an object-oriented programming language, and in Python everything is an object.
Almost every object has some metadata (called?attributes) and associated functionality (called?methods).
Even these attributes and methods of objects are themselves objects with their own type information.
Every object can be assigned to a variable or passed as an argument to a function.
Python mutability refers to being able to change an object. Simply put, a?mutable?object can be changed, but an?immutable?object cannot.
For example, a?tuple?is an immutable data type. You cannot change its elements after creating it:
nums = (1, 2, 3)
nums[0] = 100 # ERROR!
In contrast, a?list?is a mutable collection. You can change its contents afterward:
nums = [1, 2, 3]
nums[0] = 100 # Works
How to Understand Python Mutability
Everything in Python is an object. Each object falls into the category of being mutable or immutable.
When you create a Python object it gets a unique object id under the hood. Depending on whether the type is mutable or immutable, its state can be changed.
Here are some common data types and the related mutability:
But what does immutability really mean behind the scenes in Python? How could you find out whether something is mutable or not? And how come is an?int?is an immutable type? You can change an integer, can’t you?
To figure out the answers to these questions, please read along.
Before taking a deeper look at Python mutability, you need to learn what the built-in?id()?function does.
The id() Function in Python
Each and every Python object has a unique ID that is related to the memory location of a Python object.
The?id()?function returns this object ID.
For instance:
word = "This is an example"
print(id(word))
Output:
4557539968
This shows you that the?id?is a random integer value that represents the memory location of the string.
Mutability in Python
A mutable object can be changed but an immutable object cannot.
As you know, an integer is an immutable type in Python.
Let me demonstrate how you can realize this by running some experiments. First, let’s create two variables?a?and?b. The variable?a?is an integer, and the variable?b?refers to?a:
a = 1
b = a
Now both?a?and?b?point to the same memory address. In other words, the?id()?function should return the same ID for both integers:
a = 1
b = a
print(id(a) == id(b))
Output:
True
And this is indeed the case.
But now, let’s change the value of?a:
a = 10
Now, let’s compare the IDs of?a?and?b?again:
print(id(a) == id(b))
Output:
领英推荐
False
The IDs don’t match anymore. This is because now?a?points to a different integer object. In other words, the integer object?1?itself never changed. But the variable?a?that pointed to it now points to another integer object called?10.
So even though it looks as if you updated the original integer object, you did not. This is due to the fact that an integer is an immutable type in Python, and you cannot change an immutable object after creation.
Now, let’s repeat a similar experiment with a mutable object.
For example, let’s create a list:
nums = [1, 2, 3]
l = nums
Now, let’s compare the IDs of the lists:
print(id(nums) == id(l))
Output:
True
Now, let’s modify the list object by removing its first element:
del nums[0]
Let’s then check if the IDs of the two lists still match:
print(id(nums) == id(l))
Result:
True
And they do! This means?nums?and?l?still point to the same list object in memory.
To make the point clear, let’s print the contents of?nums?and?l:
print(nums)
print(l)
Output:
[2, 3]
[2, 3]
This shows that by removing the first element you were clearly able to directly modify the list object. Thus, the list object must be mutable. And this is indeed the case in Python.
To Recap
“Exceptions” in Immutability
Now that you understand mutability in Python, let’s have a look at an example that can cause confusion.
In Python,?tuples?are immutable data types. This means once you create a tuple, you cannot replace, add, or remove its elements:
nums = (1, 2, 3)
nums[0] = 100 # ERROR!
But here is where it gets interesting. If you store a list (mutable type) into a tuple, you can still change the contents of that list.
For instance:
nums = (1, 2, 3, [10, 20, 30])
#Change the first value of the list in the tuple from 1 to 1000:
nums[3][0] = 1000
print(nums)
Output:
(1, 2, 3, [1000, 20, 30])
Here you can see how the first value of the list inside the tuple changed from 1 to 1000.
But how is this possible? A tuple is immutable, so it should not change, right?
The value of a?tuple?cannot be changed after it is created. But in reality, a value of a tuple is just a name that is bound to an object behind the scenes.?These?bindings?are immutable, but not the objects they are bound to.
In other words, if a tuple element points to a mutable list, you can modify the elements of the list. But you cannot replace the list with another item in the tuple. This would break an unbreakable binding.
So the value of an immutable object?can?not?change. But the object it points to can change (if it is mutable).
Conclusion
Python mutability means an object’s ability to change. An immutable object cannot change, but a mutable object can.
For example, a list is mutable, but a tuple is not. In other words, you can freely change the elements of a list, but not the ones of a tuple.