This proves that everything in Python is an object.
So what is an object?
A Python object comprises of three parts:
Reference count is the number of variables that refer to a particular memory location.
Type refers to the object type. Examples of Python types include int, float, string, and boolean.
Value is the actual value of the object that is stored in the memory.
Objects in Python are of two types – Immutable and Mutable.
It is important to understand the difference between immutable and mutable objects to implement pointer behavior in Python.
Let's first segregate the data types in Python into immutable and mutable objects.
Immutable objects cannot be changed post creation. In the above table, you can see that data types that are commonly used in Python are all immutable objects. Let's look at the below example.
When you run this script in your REPL environment, you will get the memory address of value.
Now, let's modify the value of x and see what happens. The value of x in the memory 94562650443584 is 34 and that cannot be changed. If we alter the value of x, it will create a new object.
Use the is() to verify if two objects share the same memory address. Let's look at an example.
x = y
x is y
If the output is true, it indicates that x and y share the same memory address.
Mutable objects can be edited even after creation. Unlike in immutable objects, no new object is created when a mutable object is modified. Let's use the list object that is a mutable object.
numbs =[1,1,2,3,5]print("---------Before Modification------------")print(id(numbs))print()## element modification
numbs+=1print("-----------After Element Modification-------------")print(id(numbs))print()
-----------After Element Modification-------------
Note that the address of the object remains the same even after performing an operation on the list.
This happens because list is a mutable object. The same concept applies to other mutable objects like dict or set mentioned in the table presented earlier in this tutorial.
Now that we have understood the difference between mutable and immutable objects, let us look at Python's object model.
Variables in C vs Variables in Python
Variables in Python are very different from those in C or C++.
More specifically, Python doesn't have variables. They are called names instead. To understand how variables in Python differ from that in fundamental programming languages like C and C++, let's look at an example.
First, let's define a variable in C.
int v =10;
What does the above code actually do?
This single line of code:
Allocates a memory for the defined data type, which in this case is int
Allocates a value 10 to the memory location, say 0x5f3
Indicates that the variable v takes the value 10
In C, if you want to change the value of v at a later point, you can do this.
int v =20;
Now, the value 20 is allocated to the memory location 0x5f3. Since the variable v is a mutable object, the location of the variable did not change though the value of it changed. That is, the v defined here is not just the name of the variable but also its memory location.
Now, let's assign the value of v to a new variable.
int new = v;
A new variable new is now created with the value 20 but this variable will have its own memory location and will not take the memory location of the variable whose value it copied.
In Python, names work in a contrasting way than what we just saw.
Let's rewrite the Python equivalent of the above code to see this principle in action.
This single line of code:
Creates a new Python object
Sets the data type for the Python object as integer
Assigns a value 10 to the PyObject
Creates a name v
Points v to the newly created PyObject
Increases the refcount of the newly created Python object by 1
Let's visualize and make our understanding simple.
Unlike in C, a new object is created and that objects owns the memory location of the variable.
The name defined v, does now own any memory location.
Now let's assign a different value to v.
int v = 20
Let's see what happens here:
First this creates a new PyObject
Sets the data type for the PyObject as integer
Assigns a value 20 to the PyObject
Points v to the newly created PyObject
Increases the refcount of the newly created PyObject by 1
Decreases the refcount of the already existing PyObject by 1
The variable name v now points to the newly created object. The first object which had a value 10 now has a refcount equal to zero. This will be cleaned by the garbage collector.
Let's now assign the value of v to a new variable.
int new = v
In Python, this creates a new name and not a new object.
You can validate this by using the below script.
new is x
The output will be true. Note that new is still an immutable object. You can perform any operation on new and it will create a new object.
Pointer Behavior in Python
Now that we have a fair understanding of what mutable objects are let us see how we can use this object behavior to simulate pointers in Python. We will also discuss how we can use custom Python objects.
Using Mutable Object:
We can treat mutable objects like pointers. Let's see how to replicate the below C code in Python.
void add(int *a)
*a += 10;
int v = 10;
add(&v); // to extract the address of the variable
In the above code, v is assigned with a value 10. The current value is printed and then the value of v is increased by 10 before printing the new value. The output of this code would be:
v = 10
v = 20
Let's duplicate this behavior in Python using a mutable object. We will use a list and modify the first element of the list.
v += 1
new = 
Here, add() increments the first elements value by one. So, does this mean pointers are present in Python? No! This was possible because we used a mutable type, list. Try the same code using tuple. You will get an error.
new = (10,)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in add_one
TypeError: 'tuple' object does not support item assignment
This is because tuple is an immutable type. Try using other mutable objects to get similar desired output. It is important to understand that we are only faking pointer behavior using mutable objects.
Pointers Using ctypes
We can create real pointers in Python using the built in ctype modules. To start, store your functions that use pointers in a .c file and compile it.
Write the below function into your .c file.
Assume our file name is pointers.c. Run the below commands.