Python3: Mutable object or Immutable object!
Everything is an object in python!
And every object has an identity, type, and value, but objects can be Mutable or Immutable, this is what this blog post is about, so let’s dive into the issue. We are going to see different concepts so, be aware of the details.
What are objects?
An object is basically something a variable can refer to, and it combines data values with behavior. So objects represent information but also behave depending on the data, for example when an object is printed, it knows the corresponding text output, so objects are process and data, connected together to represent properties, behaviors, and interactions. As everything is an object in python, it can be said that there are more complex objects than others.
Objects also have methods, depending on the type of the object those methods can be different, i.e. append is a method for some sequence objects like the lists.
>>> list_int = [1, 2, 3]
>>> list_int.append(4) # Add an element to the end
[1, 2, 3, 4]
Id and Type:
The method id() is a general function that returns the “Identity” of an object. This identity is a number, that is unique and constant, and it belongs to the object while it exists, so you can see this as the address of the object in the memory.
type() returns the class type of the object passed, as I mentioned before, objects have a type, different types in python are actually classes. When we create an integer and assign a variable to it, we are giving a name to the instance or object of class ‘int’.
In the image, we have our variable ‘a’, which is the name or instance symbol for ‘55’, and it is an ‘int’ with the id ‘9064352’ (this value is different in all machines and may change over user sessions). But now, let’s see this:
We have ‘b’, it is the instance name and ‘55’ is the object, if you look closer you can see that it has the same id that ‘a’, actually a and b refer to the same thing, python do this for optimizing purposes, so different names refer to the same thing, as we can see below:
a is b and a ==b, ‘is’ means literally is, and == means both names have the same values.
It does not happen the same way with all python data types:
In this example, we create lists of integers, they have the same values but are different instances.
This is slightly different that what happened with the numbers.
In this case, ‘a’ and ‘b’ refer to the same list of integers, this is called aliasing. The behavior is different depending on the object type if it is mutable or immutable.
Mutable and Immutable Objects:
Basically Mutable Objects in python are those in which the state can be changed after the creation, while the immutable can’t change their state after they are created.
Lists, dictionaries, bytearray, set, dict(), classes, class instances.
Integers, floats, strings, tuples, complex, frozenset, bytes.
As strings are immutable, when we try to change one of its values, there is an error, but lists can change values and size dynamically (the same object with the same id but different values and size).
Immutable objects exception:
As mention before tuples are immutables objects, but they can change! Confused?
We actually tuples are immutable, but tuples contain references to other objects, so those objects may or may not change while the tuples don’t. It is important to understand that the object “value” in this case doesn’t change while the constituent object may change if it is a mutable object. Let’s see it with an example:
In this case, there is a list in the tuple, so we can modify this list but the tuple has the same id, it is the same object.
Why is it important and how to use it?
Effective programming requires organization and a correct structure, it is important to know what is your program objective and how to make it happen, objects allow modular programming, it means a big problem is divided incoherent parts that can be separately developed and maintained to finally being put together.
- Immutable objects are useful when you want to keep the object as originally created.
- To change variables referred to as an immutable object is more expensive in terms of method and memory.
- Mutable objects can change size and value during their lifetime more easily.
- Immutable objects are quicker to access than mutable objects.
How arguments are passed to functions and what does that imply for mutable and immutable objects:
To explain this first we must understand the “state” concept, it implies an evolving process in which the object change or not, so that mutable objects have local state, it means their values can change at any point in the execution program by making statements of the object with the corresponding method.
Functions also have a local state, when we create a function it will be in a global frame, and after the def statement, we can call it, passing or not arguments depending on the function. Here the important is how python handle this.
Assignment in python actually passes references to the object, when we call a mutable object in a function by references and we change it, you can change the original object value itself, but with immutable objects it doesn’t work, because the original value can’t be changed, so in a function we actually modify a copy of the original passed argument inside the function. The local state doesn’t change the object if it is immutable.
As you can see the mutable object changes if we modify the object reference, now let's see what happen with an integer (immutable):
As you can see in the example a variable num refers to the integer object “10”, when we pass it to a function, will only modify the local variable so while we pass the object “10” in variable num, and it has the same id inside the function that outside of it, that variable only change locally because y create a copy, the integers objects are immutable. The easy way to change the “num” variable that lives outside the function is returning the modified value and assigning it tho “num”.
Integer objects in Python:
If you look at the example carefully you will realize that the integer object ‘10’ has the same id inside and outside the function, so both variables refer to the same instance, why? because of python3 behavior, once you create an integer from -5 to 256, the interpreter creates an array of integers from -5 (inclusive) to 257 (non-inclusive) and allocate it in the memory for fast access and performance, those are commonly used numbers. They are defined as the
NSMALLNEGINTS macros. But if you create numbers outside that range you will create new instances.
#define NSMALLPOSINTS 257
#define NSMALLNEGINTS 5
So as in python, everything is an object, it is very important to understand these basic concepts because we will use it all the time, and doing it we can take better decisions according to the objectives we pursuit when coding.
I hope this has been a useful blog for you, good luck!