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 requeststo 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
NameErrorexceptions 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
requestswas deleted with the del statement, the module still remains loaded, as can be seen when accessing thesys.modulesdictionary using the key'requests'. - Only deleting the key from
sys.modulesdictionary (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 functionthe 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
NameErrorexceptions, 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.