Python is an object-oriented programming language where we don't have to worry about managing memory space in Python. It has a "Python memory manager", which is responsible for memory allocation and memory management, hence no need for any manual intervention. Yet, sometimes there are conditions that demand to have a look in the memory space.
Let's take a look at the most basic memory unit, aka variables in Python, and see how memory works while dealing with them.
What is a Variable in Python?
A Variable is generally defined as a name assigned to that memory space that holds values. The word 'variable' itself refers to that the values can vary for the same space. You must be wondering if it is the same for all programming languages. You'll be surprised to learn that, everything in Python is an object. Variables, Lists, Tuples, and even classes are instances.
Variables are references to the actual objects which hold the given value. That's why in Python we don't have to declare the variables or their data types before using them.
For example:
# declaring variable without data type var1 = 5 print(var1) # type of variable 1 print(type(var1)) # using variable without prior declaration for i in range(2): print(i)
See how we have declared a variable and used a variable without any hassle of declaring data types or initializing.
Output:
5 <class 'int'> 0 1
Notice how the type(var1) returns <class 'int'>. This implies that variable var1 is an instance of class integers.
Sounds Confusing? Don't worry, let's take a look into how memory management occurs in Python when a variable is declared.
How is Memory Managed in Python?
While working with Python, there are two types of memory:
1. Static Memory
2. Dynamic Memory
Python uses dynamic memory allocation, i.e. memory allocation occurs during runtime. The dynamic memory allocation uses a Heap data structure for implementation. Besides heap data structure, the Stack data structure is used to store the static memory. Don't get confused between static memory and dynamic memory in Python.
Here, static memory refers to the function call stack. Recall the function call sequence stored using stack in Recursion. As compared to other programming languages, Python doesn't involve manual memory management.
Python has a Python manager which manages the application data in memory, hence not much human intervention is required while dealing with memory space.
What occurs When we Declare a Variable in Python?
Variables in Python are references to not only constants or values, but they are also referenced to objects. When we declare a variable in Python, it creates an object in the Private Heap Space that stores the variable's value. While the variable gets created in the Stack memory as a reference to the said object.
Hard to understand? Let's look at an example. Assume you need to declare a variable; consider the variable name 'a,' with the value 5! Now, look at the image below to see what goes on behind the scenes!
As you see, the object, which stores the value (5) is created in the Private Heap Space while the variable/reference to that object gets created in stack memory. Now let's consider creating another variable, say 'b', with the same value as 'a'. Can you guess how the memory allocation will take place now?
The Python memory manager will generate another reference 'b' to the same object (storing 5) referenced to by 'a' since it's the same value. As a result, there will be two references to the same object. Any change in either of the references will lead to breakage of their reference link to that object (storing 5) and say, the creation of another object.
You can think of variables in Pythons as pointers (as in C, and C++) to the objects.
Why do we need to Delete Variables?
Memory Management is one of the key consideration factors when dealing with software development in Python or any programming language. You must be wondering why this Memory Management is so important. You don't even notice how it affects your code while writing any program.
Well, let me tell you, this is because you haven't dealt with large software working on a large amount of data, or big data, yet. When dealing with big data, you'll notice how this memory management affects your software's overall efficiency and processing time.
Data structures were introduced for this reason!
How does Variables Deletion work?
As said earlier, Python has a Python memory manager, which is responsible for the allocation or de-allocation of the memory heap. The memory Heap in Python holds the objects and other data structures used in the program.
So, when a variable (a reference to an object) is no longer in use, the Python memory manager frees up the space, i.e. it removes the unnecessary object. This process of removing objects, which are no longer in use, is known as Garbage Collection.
Garbage Collector
Garbage Collector is a process that runs in the background of your Python program. As soon as you execute the Python program, the garbage collector also starts in the background. Hence, a garbage collector doesn't need to be triggered or called upon specifically. This process runs on a regular basis and reclaims memory space from objects that are no longer needed by the program.
How'll the Garbage Collector determine if a variable (object) should be deleted? Well, it's pretty simple. Since Python has everything as objects, thus each object must have references. As discussed above, an object can have more than one reference. As soon as you create a variable, its object gets created in the Private Heap Space.
Now, let's go back to our example. Since the object (storing 5) has two references 'a' and 'b'. Now assume that you have to delete variable a. What do you think can occur in the memory?
So, the object won't get deleted itself, since it has a reference (variable 'b') pointing at it. But the reference (variable 'a') is removed.
The number of references to an object is stored. This is known as Reference Counting in Python.
So, if we talk about the above example, our object (storing 5) had 2 references, variables 'a' and 'b'. Hence, the Reference Count for our object (storing 5) will be 2. The Garbage Collector won't discard this object till its Reference Count returns to zero. This means that until both the variables ('a' and 'b') get deleted, the object (storing 5) won't be discarded.
Like the image below:
But this classical approach also falters when dealing with reference cycles. Now, let's look at how to delete these variables in Python.
How to Delete Variables in Python?
So far we've discussed how memory allocation and de-allocation occur in Python. Although Python has a Garbage Collector and Memory Manager to deal with memory space automatically, there are some cases where you need to force memory cleaning.
For instance, when dealing with large amounts of data or developing software that consumes a lot of memory space. In Python, there aren't many ways to delete variables. Some of the well-known methods are as follows:
01) Using the del keyword
Using the 'del' command is the most known and easiest method to delete variables in Python. The del keyword deletes the objects. Since everything in Python is an object, therefore lists, tuples and dictionaries can also be deleted using 'del'. It has a really simple syntax.
Syntax: del variableName
For example, let's delete a variable 'a'.
# Example -> Deleting a variable in Python using 'del' keyword # declaring variable a = 25 print("variable: ", a) # deleting the variable del a # calling out the variable again print("variable: ", a)
You must be wondering how will you know if the variable is deleted. Try calling the variable again after deleting it.
Output:
variable: 25 Traceback (most recent call last): File ".\temp.py", line 10, in <module> print("variable: ", a) NameError: name 'a' is not defined
Notice the NameError error obtained on calling the variable 'a' again, after deleting it. Hence, this proves that the variable 'a' is deleted using the del keyword.
While using the del keyword to delete variables in Python, you must be sure if you actually don't want to access the variable later on at any stage in your program. Unnecessary deletion of variables (objects) can lead to error. You won't be able to access these deleted variables, once deleted, from the program.
02) Deleting Multiple Variables in Python
You can also delete multiple variables together in Python using the del keyword. It is similar to initializing multiple variables in one line, separated by a comma.
Syntax : del variableName1, variableName2, variableName3
Example:
# Example -> Deleting multiple variables in Python # declaring multiple variables a, b, c = 5, 10, 15 print("variables: a: ", a, " b: ", b, " c: ", c) # deleting multiple variables del a, b, c # calling out the variable again print("variables: a: ", a, " b: ", b, " c: ", c)
Deleting multiple variables is similar to deleting a variable in Python.
Output:
variables: a: 5 b: 10 c: 15 Traceback (most recent call last): File ".\temp.py", line 10, in <module> print("variables: a: ", a, " b: ", b, " c: ", c) NameError: name 'a' is not defined
Note how the NameError error only pointed out variable 'a'. Python is an interpreted language, which means that it interprets commands line-by-line. Since variable 'a' is the first undeclared variable encountered, hence the execution process pauses at the first error. Thus, the NameError error points out only the variable 'a'.
03) Using dir() and globals()
You can also delete "All variables" in your program at once. By "All Variables" I mean the user-defined variables in the local or global scope of your program. As you know, the dir() method returns the all properties and methods of a specified object. Even when no object is referenced, it returns a list of all the variables and built-in methods used in your program.
For example:
# declaring multiple variables a, b, c = 5, 10, 15 print("variables: a: ", a, " b: ", b, " c: ", c) #inititalizing d with dir() d = dir() #printing the directory print(d)
You'll notice that print(d) prints out the list of all the variables and methods in the given program.
Output:
variables: a: 5 b: 10 c: 15 ['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'a', 'b', 'c']
Our user-defined variables ('a', 'b', and 'c') are at the bottom of the list. The double underscores (__) used as a suffix and prefix, distinguish a user-defined variable from a built-in variable or method.
At the same time, the globals() method returns a dictionary with all the global variables and symbols for the program along with their values. For example -
# declaring multiple variables a, b, c = 5, 10, 15 print("variables: a: ", a, " b: ", b, " c: ", c) # inititalizing g with globals() g = globals() print(g)
You'll notice the difference between the dir() and globals() method with the following output:
variables: a: 5 b: 10 c: 15 {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x00000254F32FEB08>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': '.\\temp.py', '__cached__': None, 'a': 5, 'b': 10, 'c': 15, 'g': {...}}
At the end of the dictionary, note our defined variables are printed, along with their values.
Now, let's begin with deleting these user-defined variables. You'll need to check if the variable name holds any double underscores ('__') or not, in order to distinguish between user-defined and built-in variables.
# Example -> Deleting all variables in Python a, b, c = 5, 10, 15 print("variables: a: ", a, " b: ", b, " c: ", c) #initializing d with dir() #This will store a list of all the variables in the program d = dir() #You'll need to check for user-defined variables in the directory for obj in d: #checking for built-in variables/functions if not obj.startswith('__'): #deleting the said obj, since a user-defined function del globals()[obj] #calling the variables again! print("variables: a: ", a, " b: ", b, " c: ", c)
Take note of the syntax for removing variables. First, we must determine whether the variable (object) is user-defined or not by looking for ('__') in the prefix. If the object is user-defined, we must remove it from the globals (). We can pass the object to globals() for deletion because it is a dictionary.
Output:
variables: a: 5 b: 10 c: 15 Traceback (most recent call last): File ".\temp.py", line 17, in <module> print("variables: a: ", a, " b: ", b, " c: ", c) NameError: name 'a' is not defined
And Voila!! The user-defined variables are deleted. All at once!
Conclusion
Memory management is an important factor when it comes to the computational efficiency of a program or software. Although Python has its own Memory Manager and Garbage Collector, we can also trigger a garbage collector or delete variables in order to redeem the memory space. The 'del' keyword can be used to delete objects in Python. The word 'object' includes variables, lists, tuples, sets, dictionaries, and almost everything in Python. Try to implement the above methods to delete the other objects. You'll be surprised with the result each time.