How to Remove Imported Modules in Python: Techniques and Caveats
While Python is not designed for dynamically unloading modules, there might be situations where you need to try to remove an imported module.
This guide explores the techniques to achieve this, including using the del
statement and sys.modules
, as well as an alternative approach using importlib.reload()
. We'll also emphasize why unloading modules can be problematic.
Attempting to Remove a Module
To attempt to remove a previously imported module, you need to remove both the reference in sys.modules
and the direct variable assignment.
import sys
import requests
print(requests.get) # Output: <function get at 0x...>
# Attempt to remove the imported module
del sys.modules['requests']
del requests
try:
print(requests.get) # Causes NameError exception
except NameError as e:
print(e)
# Output: name 'requests' is not defined
- First you remove the module reference from
sys.modules
, which is a dictionary that maps module names to already loaded modules. - Then you use
del requests
to remove the direct reference to the module name in your code. - However, Python doesn't guarantee that the module will actually be unloaded, as there may be other references to it elsewhere in your program, and after unloading it is possible that you will get
NameError
exceptions if you attempt to access it. - The module will only be unloaded from memory once there are no references to the module.
Removing from sys.modules
As demonstrated in the example above, deleting the name requests
and deleting the key requests
from sys.modules
is needed to attempt unloading the module:
import sys
import requests
print(requests.get) # Output: <function get at 0x...>
del requests
print(sys.modules['requests']) # Output: <module 'requests' ...>
del sys.modules['requests']
#print(sys.modules['requests']) # raises exception
- Even if the name
requests
was deleted with the del statement, the module still remains loaded, as can be seen when accessing thesys.modules
dictionary using the key'requests'
. - Only deleting the key from
sys.modules
dictionary (and also deleting the variable) will allow the module to be removed from memory and for the python interpreter to be able to release the memory the object occupies.
Reloading a Previously Imported Module
Instead of attempting to remove a module, a more common approach is to reload it using importlib.reload()
. This is especially useful when you've made changes to a module’s source code:
from importlib import reload
import requests
if len('a') == 1: # Just a condition to run the reload function
requests = reload(requests)
print(requests.get)
# Output (The address will be different than it was before reload)
# <function get at 0x...>
- The
importlib.reload()
method reloads the module in place. - This will make your code use a newer version of the module. Note that this does not reload the module globally, just the module that was imported, so if you use
from module import function
the old version of the function will still be available. - The module has to be imported first and the method returns the reloaded module.
Limitations and Caveats
- Not a Standard Practice: Python is not designed for dynamically unloading modules. Once a module is loaded it usually remains in memory throughout the session.
- Potential Errors: Unloading modules can lead to unpredictable behavior and
NameError
exceptions, especially if there are other references to the module or objects from the module. - Alternative: Instead of unloading, consider restructuring your code to use functions or classes and avoid module-level state for resources that you intend to release.
- Use with Caution: If you are not very careful about unloading, you might get errors in code that depends on the module.
- Limited Effect: The techniques shown in this guide might not always lead to the module actually being unloaded, as there could be other references to the module in your program.