Python3: Mutable, Immutable… everything is object!
A controversial title, no? So what does it mean that everything in python is an object? Everything is an object in the sense that it can be assigned to a variable or passed as an argument to a function. Actually almost everything in python has attributes or methods. For example, an integer in Python is an object or a string, absolutely everything is an object.
Let’s assign some values to a variable. Which essentially means that we make example refer to the “Holberton” object of type string.
And the same values to another variable:
As can be seen in the examples, example and example_2 have the same identity. That means they both refer to the same values (objects) and no other space was allocated for the new string with identical values. It is safe to do this in Python, as strings are immutable, so this is the way to optimize resources by referring two strings that refer to the same string to the same object (“Holberton”).
To better understand let’s do the following queries to python
Ok but…. now that we are done understanding this, let’s look at an exception within this rule:
Not respecting the previous rule, we can see that the lists used as example are the same, but they are not the same object.
To better understand how objects work in Python, we would need to understand the id and type functions. The id () function in Python returns the identity of the object. This is an integer that is unique to the given object and remains constant forever
ID Function
Syntax: id (object): the identification of the object will be returned.
TYPE Function
The type () function returns the type of the object.
Syntax: type (object): the type of the object will be returned.
So, we need undertstand two concepts, mutable and inmutable
Mutability and immutability in Python is that variables can change (mutable) or not (immutable) Can’t you change the content of any variable, unless they are “final”? Yes, that they are “final” means that the variable will be a constant and that it will never change throughout the execution of the program code. Actually the value of the variables “below” change some yes and others no even though it seems that they really change.
Mutable objects in Pythons are lists, dictionaries, set, byte array. Mutable means that you can change object’s content without changing it’s identity.
Inmutable objects like strings, integers, floats, tuples, frozen set, bytes, complex can not be changed. (exception: tuples and frozen sets [because they are containers and can contain mutable objects like lists for example])
Example of immutable objects:
As we can see assignment to the position [1] is not possible. We can not change the values that string refers to.
If we want to add values to our string, we can just add (+) another string to the existing one by: example += “new values”
It changed! Which means that no new values were added to the original string, but a new string was created, which of course has it’s own identity.
Mutability and immutability are both are very important. If you need to create a large string, it would be very inefficient to keep concatenating all newly created strings. In that case you would want to use list comprehension, which is a mutable type. On the other hand, immutability is very important when you want to make sure your original will never be changed.
So, now…
An integer object in Python
To avoid allocating a new integer object each time a new integer object is needed, Python allocates a block of free unused integer objects in advance. PyIntObjects structure is used by Python. The array of 262 integer objects is initialized. They don’t have any values assigned to them — they are free integers that are ready to be called and used whenever needed. It speeds up the process, because you don’t need to create a new object when you need to use an integer, the value will simply be assigned to the next available object and no memory allocation will be necessary.
The value range of these integer objects is -5 to 257 — because they are the most used integers and they are defined like that:
#define NSMALLPOSINTS 257
#define NSMALLNEGINTS 5
When you assign a value to a variable (variable passed to a function by assignment) it will check if the integer is in range of -5 to 257 and return the integer object pointed by the small integers at the offset.
Names and objects Objects
Have individuality and multiple names can be linked to the same object. This is known as aliasing in other languages. This is usually not apparent at first glance in Python and can be safely ignored when dealing with immutable basic types such as numbers, strings, tuples, etc. However, aliasing has a possibly surprising effect on the semantics of Python code involving mutable objects. like lists, dictionaries, and most other types. This is generally used to the benefit of the program, since aliases behave like pointers in some respects. For example, passing an object is cheap since the implementation only passes a pointer; and if a function modifies an object passed as an argument, the caller will see the change. This eliminates the need for two different mechanisms to pass arguments which we know as passing the variable by value or by reference.
In this part I want to express my opinion about the 0x09-python-everything_is_object project, it was a totally different project from all the previous ones, in which we hardly programmed but required us to work as a team and discuss how the different objects would behave in different situations . This project was more entertaining compared to the previous ones, and it greatly strengthened team thinking before taking it to the pc.
I hope this blog has been helpful for you to better understand how objects work as it can be a bit confusing. Any questions you have, do not hesitate to write me, I hope you have a great day or night.