DEV Community

Cover image for Python Variables and Memory Management
Sweta Shaw
Sweta Shaw

Posted on • Originally published at swetashaw.hashnode.dev

Python Variables and Memory Management

Variable

Variable is a way to refer to memory locations being accessed by a computer program. In languages like C, C++, Java, a variable is a name given to a memory location. So when we say:

int x;
float y;
Enter fullscreen mode Exit fullscreen mode

It asks the compiler to create memory space for two variables, 4 bytes each (size depends on the compiler and programming language). Variables are basically names assigned to the memory locations and if the variable is of type integer only integer values can be stored in it.

c_x.png
But in python, we do not need to declare a variable beforehand like int x, we can straightaway move to define the variable and start using it like x = 10.
So how does Python know what is the type of the variable and how to access it ?

In Python, everything (integer, list, string, functions, etc. ) is an object and every object has a unique id that is assigned to it when the object is created. Variables are references (pointers) to these objects. What happens when we say :

x = 10
Enter fullscreen mode Exit fullscreen mode
  • Python executes the right-hand side of the code
  • Identifies 10 to be an integer
  • Creates an object of Integer class
  • Assigns x to refer the integer object 10

variable.png

When we create another variable y which is equal to x, what do you think happens internally?

y = x
Enter fullscreen mode Exit fullscreen mode

y now refers to the same object as x.
x_and_y.png

How do we know that?
It can be verified by checking the id of the object that these two variables x and y are pointing to.

id(y) == id(x)
# output
True
Enter fullscreen mode Exit fullscreen mode

We can also print the id of the object

print(f"id of the object pointed by x:{id(x)}")
print(f"id of the object pointed by y:{id(y)}") 

# output
#your id value might be different from mine but the two ids printed must be same
id of the object pointed by x:140733799282752 
id of the object pointed by y:140733799282752
Enter fullscreen mode Exit fullscreen mode

Now, what if we assign a different value to y?

y = 40
Enter fullscreen mode Exit fullscreen mode

This will create another integer object with the value 40 and y will now refer to 40 instead of 10.

x_and_y_diff.png

How can we check?
Again, we will use id() to see the ids of the objects.

print(x) # outputs 10
print(y) # outputs 40
Enter fullscreen mode Exit fullscreen mode
print(f"id of the object pointed by x:{id(x)}")
print(f"id of the object pointed by y:{id(y)}")  

# output
id of the object pointed by x:140733799282752
id of the object pointed by y:140733799283712
Enter fullscreen mode Exit fullscreen mode

As we can see from above, the two ids are now different which means a new object with value 40 is created and y refers to that object now.

If we wish to assign some other value to variable x

x = "python"
print(id(x))

# output
1783541430128
Enter fullscreen mode Exit fullscreen mode

We will get an object id that is different from the id "140733799282752" printed by id(x) for integer object 10 previously.

So what happened to the integer object 10? The integer object 10 now remains unreferenced and can no longer be accessed. Python has a smart garbage collection system that looks out for objects that are no longer accessible and reclaims the memory so that it can be used for some other purpose.

xy.png

One last question: What if we create two integer objects with the same value?

p = 100
q = 100
Enter fullscreen mode Exit fullscreen mode

Before I answer this question. Let's check their ids:

print(f"id of the object pointed by x:{id(p)}")
print(f"id of the object pointed by y:{id(q)}") 
# output
id of object pointed by x:140733799285632
id of object pointed by y:140733799285632
Enter fullscreen mode Exit fullscreen mode

So what python does is optimize memory allocation by creating a single integer object with value 100 and then points both the variables p and q towards it.

Let's check one more example-

m = 350
n = 350

print(f"id of object pointed by x:{id(m)}")
print(f"id of object pointed by y:{id(n)}") 

# output
id of object pointed by x:1783572881872
id of object pointed by y:1783572881936
Enter fullscreen mode Exit fullscreen mode

To our surprise the ids of the integer object 300 referred to by m and n are different.

What is going on here??

Python allocates memory for integers in the range [-5, 256] at startup, i.e., integer objects for these values are created and ids are assigned. This process is also known as integer caching. So whenever an integer is referenced in this range, python variables point to the cached value of that object. That is why the object id for integer object 100 referenced by p and q print the same ids. For integers outside the range [-5, 256], their objects are created as and when they are defined during program implementation. This is the reason why the ids for integer object 350 referenced by m and n are different.

As mentioned earlier, variables point to the objects stored in memory. Hence variables are free to point to object of any type.

x = 10 # x points to an object of 'int' type
x = ["python", 20, "apple"] # x now points to an object of type 'list'
x = "python" # x now points to a string type object
Enter fullscreen mode Exit fullscreen mode

With this, we have come to the end of this short article on the inner working of variables. I hope you enjoyed reading it. Feel free to suggest improvements to the article or any other topic that you would like to know more about.

I have extensively used the concept of f-strings in my print statements. You can know more about it from this article.

Connect with me on LinkedIn
Instagram Github ❤️

Top comments (0)