Everything is an object in Python
“When all you have is a hammer, then everything looks like a nail” — Bernard Baruch.
If you have heard the saying from Bernard Baruch that’s written above, then you know that it means: open your mind, not everything is a nail just because you have a hammer. But even though that explanation applies for the real world, if you immerse yourself in the artificially created universe of python, then you can safely assume that everything that looks like an object is in fact an object, and anything that does not, is an object as well.
Because in Python, E-V-E-R-Y-T-H-I-N-G is an object, from the types: int, float, bool, strings and tuples; to lists, dictionaries, and many more.
Mutable Vs Immutable Objects
An immutable object is the one that cannot be changed or edited once its been created (i.e. string or float).
Python understands that if you write something in between apostrophes like the word “hello” for example, then that word becomes a string object automatically. And if we assign that string object to a variable (i.e. string_1), then the variable becomes a label for that object. Furthermore, any object can be pointed by several labels(variables) at the same time. However, if we change “hello” for “hi”, for the variable string_1, then that variable will be the label for another object, which is “hi”, who has a different id, because each object can only have one unique identifier or id.
On the other hand, a mutable object is the one that can change throughout the run-time of the program, just as a blue car that was painted red, and had its wheels replaced did not become another car, the same happens with a “list” (an example of a mutable object type) in python.
You can change some elements from it through time, but the “id” of the list would remain the same, meaning the list would be the same object throughout the run-time of the program, unless being deleted before, off course. In the following picture, you can see that we replaced the string “forty two” for the string “meaning of life”:
Bellow you can see a diagram which classifies each type in Python as mutable or immutable, and the relationship between those types and the variables that are assigned to them:
But wait, by this time you may be asking yourself, how are the objects created on python?. Well there are objects that come by default, like the ones mentioned above (tuple, int, string, etc.), and some that we as users can create.
Classes and Instances
The first step to create an object, is through a class. A class is like a blueprint, in which the general requirements are written, like in cars, some basic requirements to consider are: it needs to have wheels, engine and doors for people to be able to enter. We don’t need to specify what color, or how powerful the engine needs to be at the class level, we can leave that to the instance level. The instance is the same as the object that belongs to the class.
Let's say we make a class Car, so the object in this class is off course a car, but personalized; meaning it has some specific attributes. Let say we want to build a blue Camaro with an engine of 3000 cc and two doors, or we could make another Car object (a caprice) that’s yellow, with 1300 cc, and four doors. Both of them are cars but with different attributes, which in python are called instance attributes, precisely because they can be different for each object.
How arguments are passed to functions
When you pass an object as an argument in a function, what python does is to pass a new reference (or label) of that object into the function, so for example, if we pass a list (mutable object) as an argument, changes can be made to the list from within the function through the new reference that points to it. Remember, a new reference does not mean a new copy of the list, so thats why every change made to the reference is made to the original list itself, like we can see in the picture bellow:
But off course if you assign n to point to the object v is pointing, then if you print n is going to print [4, 5, 6] but l1 would still print the original list [“Item changed”, 2, 3], like you can see in the example bellow:
If you don’t want an argument in a function to modify your original list, then you need to use pure functions, which are the ones that make a copy of the object first, and then work on that copy, like you may see on the next image: