Python3: Mutable, Immutable... everything is an object!
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.
type() and id()
The type() function returns the type of the object. The returned type is a class as each object is an instance of the corresponding class. Class is a structure used to describe and access a particular value’s information and methods.
>>> a = 5 >>> type(a) <class 'int'> >>> b = "hello" >>> type(b)> <class 'str'>
When we assign a value to a variable what really happens is that we bind an object reference to refer to the object in memory that holds the data. If we want to know its address in memory we use the built-in function id() which returns a unique and constant integer for the object during its lifetime, which is its identity:
>>> id(a) 10984894 >>> b = a >>> id(b) 10984894
Mutable Objects
Mutable objects are objects that can be changed. In Python, the only objects that are mutable are lists, sets, and dicts. Take a look at this example:
>>> a = [1, 'b'] >>> type(a) <class 'list'> >>> id(a) 140211048812936 >>> a.append(4) >>> a [1, 'b', 4] >>> id(a)
140211048812936
Immutable Objects
Generally speaking, when a new object is created, a new address / Id will be assigned to it. Immutable objects will keep the same ID unless its value is changed. Immutable objects are objects that cannot be changed. In Python, this would include ints, floats, strings, user-defined classes, and more. These data types cannot be modified. This can be shown in the following example with a string:
>>> a = 5 >>> type(a) <class 'int'> >>> id(a) 10984894 >>> id(5) 10984894 >>> a += 1 6 >>> id(a) 10984894 >>> id(6)
10984894
Passing Arguments to Functions, Mutable and Immutable Objects.
In Python, everything is an object. All variables are treated as references to the object. This means that all variables store the memory address of the actual object. This is similar to the concept of pointers in C. The address of the actual object is stored in the Python named variable, not the value itself. What does this mean when it comes to passing arguments to functions, specifically regarding mutable and immutable objects? . Arguments are always passed to functions by reference in Python. The caller and function code blocks share the same object. When you change the value of an argument inside a function, the value of that variable also changes in the caller.
Immutable.
>>> def add(a): ... a += 1 ... >>> a = 10 >>> id(a) 10984894 >>> add(a) >>> print(a) 10 >>> id(a) 10984894
Mutable.
>>> def add(a): ... a.append(2) ... >>> a = [1, 3] >>> id(a) 140211048815624 >>> add(a) >>> print(a) [1, 3, 2] >>> id(a) 140211048815624
Even though an object Id remains constant during its lifetime, that’s not always true for the object value. That depends on whether the class of an object is mutable or immutable.
Why does it matter and how differently does Python treat mutable and immutable objects.
Everything is an object in Python, and this dramatically impacts the rules of the system. when an object is mutable or immutable can help us in-memory optimization, because if the lists or dictionaries were immutable data types and we wanted to modify them this would imply creating a copy and it would be slow, besides requiring a lot of memory in case they contain a lot of objects.
Sources used :
https://jarroba.com/mutables-e-inmutables/
https://ichi.pro/es/mutable-vs-inmutable-en-python-25884837532864#:~:text=Los%20argumentos%20se%20pasan%20a,se%20llam%C3%B3%20a%20la%20funci%C3%B3n.
Thanks for reading!