CodeNebula
Python🚀Advancedadvanced

The Import System

Python · Advanced · Run with python3

Explanation

`import` triggers a multi-step process: find the module (using `sys.meta_path` finders), load it (execute the source or bytecode), and cache it in `sys.modules`. Subsequent imports return the cached module. The finder/loader protocol enables custom import hooks: `sys.meta_path` for high-level control, `sys.path_hooks` for new path-based finders. `importlib.import_module()` is the programmatic import API. `__all__` controls what `from module import *` exports; `__init__.py` makes a directory a package.

Real-World Scenario

A plugin system dynamically imports modules from a `plugins/` directory at startup: `importlib.import_module(f"plugins.{name}")` loads each plugin; each plugin registers itself in a global registry via `__init_subclass__` or explicit registration in `__init__`. ```python import importlib import sys # Dynamic import def load_plugin(module_name: str): try: module = importlib.import_module(module_name) print(f"Loaded: {module.__name__}") return module except ImportError as e: print(f"Failed to load {module_name}: {e}") return None # sys.modules cache import json print(f"json cached: {'json' in sys.modules}") # True after first import cached = sys.modules["json"] print(f"Same object: {cached is json}") # True # __all__ controls wildcard imports print(f"json.__all__ (first 5): {json.__all__[:5] if hasattr(json, '__all__') else 'not defined'}") # Reload a module (rarely needed, but useful in REPL development) import math original_pi = math.pi importlib.reload(math) print(f"After reload: math.pi = {math.pi}") ```

Quick Snippet

snippet.py
import importlib
import sys

# Dynamic import
def load_plugin(module_name: str):
    try:
        module = importlib.import_module(module_name)
        print(f"Loaded: {module.__name__}")
        return module
    except ImportError as e:
        print(f"Failed to load {module_name}: {e}")
        return None

# sys.modules cache
import json
print(f"json cached: {'json' in sys.modules}")   # True after first import
cached = sys.modules["json"]
print(f"Same object: {cached is json}")            # True

# __all__ controls wildcard imports
print(f"json.__all__ (first 5): {json.__all__[:5] if hasattr(json, '__all__') else 'not defined'}")

# Reload a module (rarely needed, but useful in REPL development)
import math
original_pi = math.pi
importlib.reload(math)
print(f"After reload: math.pi = {math.pi}")

Full Example

import_system.py
# Compile: python3 import_system.py
# Output:
# json cached: True
# Same object: True

import importlib
import sys

print(f"json cached: {'json' in sys.modules}")
import json
cached = sys.modules["json"]
print(f"Same object: {cached is json}")

# Dynamic import
def load_module(name: str):
    try:
        module = importlib.import_module(name)
        print(f"Loaded: {module.__name__}")
        return module
    except ImportError as e:
        print(f"Failed: {e}")
        return None

load_module("json")
load_module("nonexistent_module")

# Inspect a module's public API
import math
public_api = [name for name in dir(math) if not name.startswith("_")]
print(f"math public names: {len(public_api)}")
print(f"First 5: {public_api[:5]}")

# Reload (rarely needed)
original_pi = math.pi
importlib.reload(math)
print(f"After reload: math.pi == {math.pi} (same: {math.pi == original_pi})")

# sys.path — where Python looks for modules
print(f"\nModule search paths (first 2):")
for p in sys.path[:2]:
    print(f"  {p!r}")
Run command
python3 import_system.py