Importlib Module¶
The importlib module provides tools for importing modules and working with Python's import system programmatically.
Complexity Reference¶
| Operation | Time | Space | Notes |
|---|---|---|---|
import_module(name) |
O(n) | O(n) | n = import depth |
find_loader(name) |
O(1) | O(1) | Check sys.modules |
reload(module) |
O(n) | O(n) | n = module size |
import_module(package) |
O(n+m) | O(n+m) | n = submodules |
resources.files() |
O(1) | O(1) | Get resource path |
Common Operations¶
Importing Modules Dynamically¶
import importlib
# O(n) where n = import depth/module size
# Prefer this over __import__()
module = importlib.import_module('os.path')
# Equivalent to: import os.path
import_module('json') # O(n)
import_module('collections.abc') # O(n)
# From cached sys.modules if already imported - O(1)
module = importlib.import_module('json')
module = importlib.import_module('json') # Second call is O(1)
Reloading Modules¶
import importlib
import mymodule
# O(n) where n = module size
# Re-executes module code
importlib.reload(mymodule)
# Useful for development when module changes
# Note: only reloads that module, not dependencies
Finding Module Loaders¶
import importlib.util
import sys
# O(1) - check if module is cached
spec = importlib.util.find_spec('json')
if spec is not None:
print(f"Found: {spec.origin}") # O(1)
# Get loader - O(1) if cached, O(n) if needs import
loader = spec.loader
# Manual import from spec - O(n)
module = importlib.util.module_from_spec(spec)
sys.modules[spec.name] = module
spec.loader.exec_module(module) # O(n)
Working with Submodules¶
import importlib
# O(n) where n = total submodules
package = importlib.import_module('email')
# Get submodule - O(m) where m = submodule size
mime = importlib.import_module('email.mime')
text = importlib.import_module('email.mime.text')
# Check if submodule exists - O(1) after first import
import email.mime.text
print('email.mime.text' in sys.modules) # O(1)
Common Use Cases¶
Conditional Module Imports¶
import importlib
import sys
def try_import(module_name, default=None):
"""Safely import module - O(n) or O(1)"""
try:
if module_name in sys.modules: # O(1) check
return sys.modules[module_name]
return importlib.import_module(module_name) # O(n)
except ImportError:
return default
# Usage
numpy = try_import('numpy')
if numpy:
# Use numpy
pass
else:
# Use fallback
pass
Plugin System¶
import importlib
import sys
class PluginManager:
def __init__(self):
self.plugins = {}
def load_plugin(self, name, module_path):
"""Load plugin module - O(n) where n = module size"""
try:
module = importlib.import_module(module_path)
# Assume plugin has 'register' function
if hasattr(module, 'register'):
plugin = module.register()
self.plugins[name] = plugin
return True
except ImportError:
pass
return False
def get_plugin(self, name):
"""Get cached plugin - O(1)"""
return self.plugins.get(name)
# Usage - O(n) per plugin
manager = PluginManager()
manager.load_plugin('plugin1', 'plugins.plugin1')
manager.load_plugin('plugin2', 'plugins.plugin2')
# Later access - O(1)
plugin = manager.get_plugin('plugin1')
Module Attribute Inspection¶
import importlib
module = importlib.import_module('collections')
# O(1) - hasattr checks __dict__
if hasattr(module, 'deque'):
Deque = getattr(module, 'deque')
# O(n) - iterate all attributes where n = module size
for attr_name in dir(module): # O(n)
attr = getattr(module, attr_name)
if callable(attr):
print(f"{attr_name}: {type(attr)}")
Checking Module Availability¶
import importlib.util
def module_available(name):
"""Check if module can be imported - O(1) cache or O(n) search"""
spec = importlib.util.find_spec(name)
return spec is not None
# Fast check with caching
available_mods = {}
def is_available(name):
if name not in available_mods:
available_mods[name] = module_available(name) # O(n) first time
return available_mods[name] # O(1) after cached
Performance Tips¶
Cache Module References¶
import importlib
# Bad: O(n) import each time
def process():
json = importlib.import_module('json')
return json.loads(data)
# Good: O(1) after first import
json = importlib.import_module('json')
def process():
return json.loads(data) # O(n) to parse, O(1) to access module
Use find_spec for Existence Checks¶
import importlib.util
# Efficient existence check - O(1) if cached or path-based
if importlib.util.find_spec('numpy'):
import numpy
# Use numpy
Batch Import Strategy¶
import importlib
import sys
def ensure_modules(module_list):
"""Import multiple modules efficiently"""
loaded = {}
for name in module_list:
if name not in sys.modules: # O(1) check
loaded[name] = importlib.import_module(name) # O(n)
else:
loaded[name] = sys.modules[name] # O(1)
return loaded
# O(k*n) where k = module count, n = avg module size
modules = ensure_modules(['json', 'os', 'sys'])
Version Notes¶
- Python 2.7: Limited support
- Python 3.1+: importlib added
- Python 3.4+: importlib.util for detailed control
- Python 3.7+: Simplified import machinery
Related Documentation¶
- Sys Module - sys.modules cache
- Pkgutil Module - Package utilities
- Runpy Module - Running modules