Python3: Mutable, Immutable... everything is object!
Brief introduction!
Object Oriented Programming (OOP or OOP) is a programming paradigm, Python is a language OOP—what does that mean? It means the Python programming language consists of objects, which allows the user to have their own methods and attributes without having to re-create them each time. The data structure of Python it is called Pyobject which is what all the data types inherit from. That is the reason of everything is an object in Pyhton.
To better understand what is related to OOP, you must have knowledge of mutable and immutable objects, to have the notion of how Python works more in depth, so...
Id and Type notions
As mentioned before, everything in Python is an object, so 'id' and 'type' they are. Lets start to show how id works, basically is used to return the identity of an object, his identity has to be unique and constant for this object during the lifetime.
Syntax: id(object)
Example: (in python3) we declare two strings to get their id's
As you can see each object has a different id, now lest assign the same value for two objects:
They id are the same, when two objects are referring to the same value, this is known as an alias. Wait, first check that they have the same 'value', it is a hint of the main topic, but first lets see 'type':
Type is an object and is used to get the type of variable passed in its argument, "returns type of the given object".
Syntax: type(object)
Example: Checks the type of variable of the object 'ob1'
Mutable objects
Mutable objects are objects whose values can change, the types of mutable objects are:
- Sequences: list(), bytearray()
- Set type: set()
- Mapping type: dict()
- Classes, class instances.
- etc.
The best way to check if an object mutates or not is checking the id's, so in the next examples we have two cases operating strings:
In the first case, the object has the same value (an alias of the other one), in consequence the same address.
The two strings at the beginning have different addresses, but using 'ob1 += ob2' (ob1 = ob1 + ob2) to concatenate these strings, the object ob1change its address by a new one, it is that way because a new object is created with the same name but a new address.
Immutable objects
These are objects that can not be manipulated, like:
- Numbers: int(), float(), complex()
- Sequences: str(), tuple(), frozenset(), bytes()
Lets to define a tuple, a next to that we try to modify the tuple to prove the immutable objects
The tuple has not that attribute because it is defined as immutable. However, for tuples and frozen sets, even though they are immutable objects, Python handles them the same way as mutable since they may contain mutable objects.
Why is important
In most applications, data integrity and consistency is usually of paramount importance. We don’t want data being mutated in odd fashions and, as a result, being erroneously stored in our database or returned to the user. We want to ensure with the best predictability that the data we are using remains consistent with what we expect. This is vital when it comes to asynchronous and multi-threaded applications.
How objects are to functions
Its important for us to know difference between mutable and immutable types and how they are treated when passed onto functions .Memory efficiency is highly affected when the proper objects are used.
For example if a mutable object is called by reference in a function, it can change the original variable itself. Hence to avoid this, the original variable needs to be copied to another variable. Immutable objects can be called by reference because its value cannot be changed anyways.
def updateList(list1): list1 += [10]n = [5, 6] print(id(n)) # 140312184155336updateList(n) print(n) # [5, 6, 10] print(id(n)) # 140312184155336
As we can see from the above example, we have called the list via call by reference, so the changes are made to the original list itself.
Lets take a look at another example:
def updateNumber(n): print(id(n)) n += 10b = 5 print(id(b)) # 10055680 updateNumber(b) # 10055680 print(b) # 5
In the above example the same object is passed to the function, but the variables value doesn’t change even though the object is identical. This is called pass by value. So what is exactly happening here? When the value is called by the function, only the value of the variable is passed, not the object itself. So the variable referencing the object is not changed, but the object itself is being changed but within the function scope only. Hence the change is not reflected.