Everything is an object...
Almost everything is an object in Python 🎈. But, what's an object? In short words, a Python object is a collection of data that had its methods and properties. The other thing we need to know is the class: it is simply a blueprint for creating objects. There are some ways to know the features of an object, we will talk about some of those rigth now.
The id() function returns the identity of an object 🆔. This information is like the object's fingerprint 👣 and it allows us to understand it behaviour. It has a simple syntax, it need just the object like argument:
id(object)
Example:
class obj(a):
a = 5
example_id = obj()
print("object's id =", id(example_id))
OUTPUT:
object's id = 17365587632
The return value is an unique integer and will be constant for the object lifetime.
Another function that allows us to know things about the objects is type() 🆎. This function is constantly used for debugging purposes 🐛 and it returns the class type of the argument. There are two ways to use it: with one or with trhee arguments.
type(object)
type(name, bases, dict)
Example:
class w_type():
a = 9
b = "Hello"
print("a is an ", type(a), " and b is a ", type(b))
OUTPUT:
a is an int and b is a str
The three arguments option has the name of the class, a tuple of classes which the class derives from and a dictionary that holds the namespaces of the class 📖.
There are some other features that we need to know about objects that we are working with. Its could be mutable or immutable class type. The word "mutable" mean that this thing could be changed and with this action the object's id will be different. In the other hand are the "immutable" thing; in this case the object can't be changed.
The class types that are mutable are:
list() - bytearray() - set() - dict()
And the immutable ones are:
int() - float() - complex() - str() - tuple() - frozenset() - bytes()
A very useful tip to know what kind of type is just use the id() function:
>>> a = 2
>>> id(a)
1
>>> a += 2
4
>>> id(a)
2
The id changed in the above example, that means the a variable is immutable (int). The below example will be the oposite of it:
>>> a = []
>>> id(a)
100
>>> a.append(1, 2)
>>> a
[1, 2]
>>> id(a)
100
In this moment you probably ask: when is a variable assigning and when is referring? 🤔 if you don't, I don't care because this is important 🙌, this is the answer: when we create a variable a = 1 a new dictionary entry is created to map the "a" string that is pointing to the new object "1".
When we change the value to a = 2, the new object is created and the dictionary now point to 👉 "2". In that way, when we do a new assigment b = a, the "b" entry is crated in the dictionary and it will point to the same object that "a".
With the goal to be clear in mind, Python make that immutable variables that have the same value refer to the same object ♊, so:
Recommended by LinkedIn
>>> a = 1
>>> b = 1
>>> a == b
True
>>> a is b
True
In the mutable case, the boolean result could be different, like:
>>> a = [2]
>>> b = [2]
>>> a == b
True
>>> a is b
False
The way to make the two lists refer to the same object is named aliasing:
>>> a = [2]
>>> b = a
>>> a == b
True
>>> a is b
True
The image below show a little better the situation:
Now, another thing that makes us think is the way that Python allocates the object in memory 😲. Again, almost everythink is an object in Python. This language stores the object in the heap and the reference of it in stack, like:
def foo():
a = 5
b = 10
Look like:
So "a" is a reference to an object type integer with the value 5 and "b" is a reference to an object type integer with value 10.
In order to be eficient, Python provide a macro with the most used integer (-5 to 256), under the names NSMALLPOSINTS and NSMALLNEGINTS. So, intead of store the number in this range, Python will search that in the heat and point it. This action avoid that Python create the object and then, when it pass to be garbage, eliminate it.
To be able to use this option, we just need to initialize NSMALLPOSINTS and NSMALLNEGINTS like:
#define NSMALLPOSINT 257
#define NSMALLNEGINT 5
This range is -5 to 256.
I hope this will be useful for you 😉.
Some references:
https://stackoverflow.com/questions/44787980/python-macros-nsmallposints-vs-nsmallnegints#:~:text=In%20the%20source%20code%20for,defined%20called%20NSMALLPOSINTS%20and%20NSMALLNEGINTS.&text=It%20turns%20out%20Python%20keeps,the%20existing%20object%20in%20memory.
https://www.w3schools.com/python/python_classes.asp
http://www.openbookproject.net/thinkcs/python/english2e/ch09.html#objects-and-values
https://stackoverflow.com/questions/9696495/python-when-is-a-variable-passed-by-reference-and-when-by-value
https://stackoverflow.com/questions/8056130/immutable-vs-mutable-types