Today’s Blog I am gong to explain what is OOP, mutable and inmutable objects.
Object Oriented Programming (OOP)
It’s a programming methodology that exist treating everything as an object, it is use for writing large programs or for solving problems that are better implementing with this method. There are four principals in OOP
- Encapsulation — The grouping of related functions and data (variables) together into an object to help reduce complexity and allow parts of the code to be reused.
- Data Abstraction — Show only the essentials to reduce the abstract of change.
- Inheritance — Eliminate redundant code by inheriting functions and data from other classes.
- Polymorphism — Change how an object function depending on the data or class.
OPP use class wrap the programs. So let’s see what is it
What is a class
A class is a template that will let us add characteristics, and actions to an object. To create a class, use the keyword
What is an object
An object sometimes can be the representation of the world, like in the image above representing 5 different cars. It is an instance of a class, and a self-contained entity that consists of data and procedures (also known as methods or functions) to manipulate the data, it lives in memory as the process exists or until destroyed.
In Python everything is an object, but not all the objects can be manipulated the same way, some are mutable and other immutable objects.
Mutables and Immutable Objects
When we create an object by instantiation, it’s given a unique ID which is the memory address in the CPython implementation. Its type is defined at runtime and once it’s set it can never change, however its state can be changed if the object is mutable.
Can be changed after they are created. Such as lists, Dictionaries and sets. The reason why we can change this objects is that they are pass by reference as argument to the function, which means passing the original object, instead of the value or a copy of it
Cannot be change after created, some examples are numbers, strings and tuples, This Objects can’t be changed because they are pass by value to the functions, so what it really means is that we are passing a copy of the object and not the original one, For example every-time we want to update a variable with a number, what really is happening is that we are creating a hole new object for that.
It is a function we use to print the type of an object
Id is a function use to get the variable identifier (which is the memory address in the CPython implementation)
How Python treat mutable and immutable objects
It is very important to understand how different mutables and immutable objects are treated in python. Deciding in create objects immutable or mutable is important by deciding on your program execution, for example if you have to make sure that some data or values don’t change, then you need to thing of a data type immutable. This will guarantee that an object remains constant throughout the program. If this is not the case then you can choose mutable objects. Let’s check how python treat both objects
Let’s start with an example of a string for Immutable objects:
var_a = "Hello"
var_b = "Hello"
There are two variables, var_a and var_b that have a value “Hello”, strings as we said before are inmutables, so one good question is, each variable is pointing to a different object with the same value (option A), or each variable is pointing to the same object, (option B)?
We can solve this by testing the two variables, checking if they refer to the same object using the operator “is” and also we can check if the value of those variables are the same by using “==”
>>> var_a = "Hello"
>>> var_b = "Hello">>> var_a is var_b #checking if both var refer to the same object
True>>> var_a == var_b #checking if the value is the same for both var
So the correct answer is option B, and because strings are immutable, python optimizes resources and memory, by referring the two variables var_a and var_b with the same value towards the same object.
In the other side python treat different mutable objects, let’s see an example using lists:
>>> list_A = [1, 2, 3]
>>> list_B = [1, 2, 3]>>> list_A is list_B
False>>> list_A == list_B
As you can see here, in the example, when comparing the value of the two lists is clear that is True that it is the same, but when we are going to heck if it is the same object, the answer is False.
The reason is, because this type of data can be modified or alter is value, so python assign to each variable its own object, even though their value is the same.
One thing that has to be clear, it when using an alias, and it occurs when we assign the value of a variable into another one such as the following example:
>>> list_A = [1, 2, 3]
>>> list_B = list_A #list_B will be an alias of list_A>>> list_A is list_B
True>>> list_A == list_B
how arguments are passed to functions and what does that imply for mutable and immutable objects
When passing arguments to functions, there are two main ways to do it, passing args by reference, and passing args by value
Passing args by value means we are passing a copy of the original object, in this example, we are passing a copy of the object to my_function, and the variable A now will refer to that copy. Then when we manipulate the value of variable A we are creating a hole new object, like in the second yellow box
Passing args by reference means we will be passing the original object to the function, so wherever change we make to the object, it will affect it. In the example below, lista contain values of a, b, and c and passing that list to the function and changing the value of it in position 1 for the value ‘x’ will change the list because it is referencing to the original object.
Tuples in Python are Immutable but potentially changing
Python tuples could be a little complicated to understand, they are immutable, but their values could be change. This may happen when a tuple holds a reference to any mutable object, such as a list.
This is an example of changing the value of a tupla that contains a list
>>> tupla = (1, 2, [3, 4])
>>> tupla = 'a'
(1, 2, [3, 'a'])
Now if we try to change the value of a tuple with non of its value mutable, then will appear an error
>>> tupla = (1, 2, 3)
>>> tupla = 'a'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
In Python every class can have instance attributes. By default Python uses a dict to store an object’s instance attributes. This is really helpful as it allows setting arbitrary new attributes at runtime.
However, for small classes with known attributes it might be a bottleneck. The
dict wastes a lot of RAM. Python can’t just allocate a static amount of memory at object creation to store all the attributes. Therefore it sucks a lot of RAM if you create a lot of objects. Still there is a way to circumvent this issue. It involves the usage of
__slots__ to tell Python not to use a dict, and only allocate space for a fixed set of attributes.
Here an example of a class
LockedClass with no class or object attribute, that prevents the user from dynamically creating new instance attributes, except if the new instance attribute is called
It turns out Python keeps an array of integer objects for “all integers between -5 and 256”. When we create an int in that range, we’re actually just getting a reference to the existing object in memory. They get allocated right when you initialize your
NSMALLNEGINTS. This is a structure to access faster to those numbers, so there is no need to create them.