Python: Mutable, Immutable… everything is object!

Maroua alaya
6 min readMay 25, 2021

Hello again, In this blog, we’ll be learning that Everything is an Object in Python . Thank you for reading and happy coding! So, let’s get started!!

I have gave a detailed explanation about Python programming you can find all the information about it in my previous blog you can see it in the link below:

Python Class Attributes VS Instance Attributes

First, we can ask some questions:

  • what are id and type functions
  • what is the difference between mutable objects and immutable objects
  • why does it matter and how differently does Python treat mutable and immutable objects
  • how arguments are passed to functions and what does that imply for mutable and immutable objects

Introduction

Python is an easy to learn, powerful programming language. It has efficient high-level data structures and a simple but effective approach to object-oriented programming. Python’s elegant syntax and dynamic typing, together with its interpreted nature, make it an ideal language for scripting and rapid application development in many areas on most platforms.

Python is an object-oriented programming language. In Python, everything is an object, whether it is a number, a function, a list, a method, a class… or even None, this means that everything in Python can be assigned to a variable or passed as an argument to a function.

ID and types

Python id() function returns an identity of an object. This is an integer which is guaranteed to be unique. This function takes an argument an object and returns a unique integer number which represents identity. The ID is a unique identifier that helps recognize the object in Python. Two objects with non-overlapping lifetimes may have the same id() value.

a = 5
print(id(a))
9785024

we can also use the built-in type() to give us what type of object we are using:

a = (1, 2)
b = [1, 3, 5]
c = "Maroua"
tel = {'jack': 4098, 'sape': 4139}
print(type(a))
print(type(b))
print(type(c))
print(type(tel))

Output

<class 'tuple'>
<class 'list'>
<class 'str'>
<class 'dict'>

mutable objects

Any object in Python whose internal state is changeable can be called a mutable. We already know by now that mutable values can change after creation. Types of mutable values in Python are:

  • Lists
  • Sets
  • Dictionaries

Lists

List data in Python are mutable. Let’s take an example:

my_list = [1,2,3,4,5,6]print(my_list)print(id(my_list))>>> [1,2,3,4,5,6]>>> 1863010210504my_list.append(7)print(my_list)print(id(my_list))>>> [1,2,3,4,5,6,7]>>> 1863010210504

Sets

A set is a random collection of the different data types which are changeable and devoid of duplication.

Here is an example for the set in Python:

lst = ['a', 'b', 'c', 'd']
my_set = set(lst)
print(my_set)
print(id(myset))
# Adding element to the set
my_set.add('f')
print(my_set)
print(id(my_set))

Output

{'c', 'b', 'd', 'a'}140114243505952{'c', 'd', 'f', 'a', 'b'}140114243505952

immutable objects

The objects with a static state or ones that can’t be changed are immutable.

Immutable objects are of type int, float, bool, string, unicode, tuple. Let’s see an example with objects of type integer:

 Number_pieces = 25
print(id(Number_pieces))
print(type(Number_pieces))
print(Number_pieces)
Number_pieces = 30
print(id(Number_pieces))
print(type(Number_pieces))
print(Number_pieces)

Output

9785664
<class 'int'>
25
9785824
<class 'int'>
30

Here, in the first instance, you may wonder whether the change in Number_pieces indicates a mutable object. But it is just an integer. The ‘int’ class is immutable and co-related to the name ‘Number_pieces.’ So, when we change the Number_pieces from 25 to 30, it points towards the ‘int’ class.

When you type 30, another object is created differently from 25. It is an object that points to ‘Number_pieces’ in a different location with another unique ID.

Let’s also talk about tuples.

Now let’s take a brief look at tuples. Tuples are immutable data structures, however they can contain mutable objects like lists inside them. While you cannot append or add new elements to a tuple once it’s been created, you can change the mutable objects stored inside a tuple. Observe the following:

tuple_1 = (1, [3, 5], "school")
print("tuple before {}".format(tuple_1))
tuple_1[1][1] = 6
print("tuple after {}".format(Tuple_1))

Output

tuple before (1, [3, 5], "school")
tuple before (1, [3, 6], "school")

How differently does Python treat mutable and immutable objects

Numbers, strings, and tuples are immutable. Lists, dictionaries, and sets are mutable, as are most new objects you’ll code with classes.

Immutability can be used to ensure that an object remains constant throughout the program; Mutable object values can be changed anywhere, anytime.

You can change a single value of a mutable data type and it won’t change its memory address. However, you can’t change a single value of an immutable type. It will throw an error.

How arguments are passed to functions and what does that imply for mutable and immutable objects

Python treats all variables as references to the object. This means all variables store the memory address of the actual object. This concept is much like “Pointer” in C and C++ programming language. This means the address of the actual object is stored in the Python named variable, not the value itself.

Python immutable objects, such as numbers, tuple and strings, are also passed by reference like mutable objects, such as list, set and dict. Due to state of immutable (unchangeable) objects if an integer or string value is changed inside the function block then it much behaves like an object copying. A local new duplicate copy of the caller object inside the function block scope is created and manipulated. The caller object will remain unchanged. Therefore, caller block will not notice any changes made inside the function block scope to the immutable object. Let’s take a look at the following example.

Example and Explanation

Immutable Function Argument:

def foo1(a):
# function block
a += 1
print('id of a:', id(a)) # id of y and a are same
return a

# main or caller block
x = 10
y = foo1(x)

# value of x is unchanged
print('x:', x)

# value of y is the return value of the function foo1
# after adding 1 to argument 'a' which is actual variable 'x'
print('y:', y)

print('id of x:', id(x)) # id of x
print('id of y:', id(y)) # id of y, different from x

Output

id of a: 1456621360
x: 10
y: 11
id of x: 1456621344
id of y: 1456621360

Explanation:

  • Original object integer x is immutable (unchangeable). A new local duplicate copy a of the integer object x is created and used inside the function foo1() because integers are immutable objects and can’t be changed in placed. The caller main block where variable x is created has no effect on the value of the variable x.
  • The value of variable y is the value of variable a returned from function foo1() after adding 1.
  • Variable x and y are different as you can see their id values are different.
  • Variable y and a are same as you can see their id values are same. Both point to same integer object.

Mutable Function Arguments

def foo2(func_list):
# function block
func_list.append(30) # append an element
print('original list:', list1)
print('list1 id:', id(list1))

print('value of list2:', list2)
print('list2 id:', id(list2))

foo2(list1)
print('\nafter foo2():', list1)
print('list1 id:', id(list1))

print('value of list2:', list2)
print('list2 id:', id(list2))

Output

original list: [10, 20]
list1 id: 24710360
value of list2: [10, 20]
list2 id: 24710360
after foo2(): [10, 20, 30]
list1 id: 24710360
value of list2: [10, 20, 30]
list2 id: 24710360

Explanation:

  • We have created a list object list1 and assigned same object to a new variable list2. Now both list1 and list2 points to the same memory where actual list object [10, 20] is stored.
  • We passed the value list1 variable into the function argument func_list. We appended, deleted and modified the list1 object element in function foo2() through argument func_list.
  • As you have noticed that actual object list1 is changed in the main block when we changed its value in the function block.
  • You should also notice that the value of list2 variable also changes when the value of list2 changes. As we have also read, this is because both list1 and list2 variable points to same list object [10, 20].
  • list1 object ID doesn’t change after every call to function foo2().This is because list1 is mutable and can be modified. Therefore, changing list1 object modifies original object value and doesn’t create the new object.

Conclusion

Everything is an Object in Python .Any object in Python whose internal state is changeable can be called a mutable. Similarly, the objects with a static state or ones that can’t be changed are immutable.

Thanks for reading!

Happy learning!

Maroua alaya

--

--