
Python
Understanding how modules are loaded and imported can help you optimize your applications and reduce startup time.
Python caches imported modules to avoid reloading them.
import sys
import math
# First import: loads module
import requests
print("requests" in sys.modules) # True
# Second import: uses cached version (no reload)
import requests
print("requests" in sys.modules) # True (same object)
# Check if module is in cache
if "requests" in sys.modules:
print("Already loaded!")The sys.modules dictionary:
import sys
# View all loaded modules
print(len(sys.modules)) # Usually 50+
# See specific module
print(sys.modules.get("math"))
# <module 'math' from '/usr/lib/python3.9/lib-dynload/math.cpython-39-darwin.so'>
# Remove from cache to force reload (rare!)
del sys.modules["mymodule"]
import mymodule # Reloads from diskMeasure how long imports take.
import time
import sys
# Time a single import
start = time.time()
import numpy
elapsed = time.time() - start
print(f"numpy import took: {elapsed:.4f} seconds")
# Subsequent imports are faster (cached)
start = time.time()
import numpy # Already in sys.modules
elapsed = time.time() - start
print(f"numpy cached import took: {elapsed:.6f} seconds") # Much faster!Using timeit for accurate measurements:
import timeit
# Time first import
time_first = timeit.timeit(
"import numpy",
setup="",
number=1
)
print(f"First import: {time_first:.4f}s")
# Time cached import
time_cached = timeit.timeit(
"import numpy",
setup="import numpy",
number=1
)
print(f"Cached import: {time_cached:.6f}s")Delay importing expensive modules until they're needed.
# ā Imports everything on module load (slow startup)
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import scipy
def analyze_data(filename):
# Only uses pandas and numpy
data = pd.read_csv(filename)
return np.mean(data)
def plot_data(data):
# Only uses matplotlib
plt.plot(data)
plt.show()
# Program starts slowly even if only analyze_data() is called!# ā
Lazy import (fast startup, import on first use)
def analyze_data(filename):
import pandas as pd
import numpy as np
data = pd.read_csv(filename)
return np.mean(data)
def plot_data(data):
import matplotlib.pyplot as plt
plt.plot(data)
plt.show()
# Program starts quickly! Imports only when functions are calledLazy module wrapper:
class LazyModule:
def __init__(self, module_name):
self.module_name = module_name
self._module = None
def __getattr__(self, name):
if self._module is None:
self._module = __import__(self.module_name)
return getattr(self._module, name)
# Usage
numpy = LazyModule("numpy")
# numpy doesn't import until first use
array = numpy.array([1, 2, 3]) # Now it importsStartup Performance:
# ā Slow startup - all imports at top
import requests
import numpy
import pandas
import matplotlib
import scipy
import sklearn
def quick_function():
return "done" # But imports all packages!
# ā
Fast startup - lazy imports
def quick_function():
return "done"
def data_analysis():
import numpy
import pandas
# Import only when neededimport sys
import time
def measure_import_size(module_name):
"""Measure memory used by a module."""
import importlib
# Get size before
before = len(sys.modules)
start_time = time.time()
module = importlib.import_module(module_name)
elapsed = time.time() - start_time
after = len(sys.modules)
print(f"Module: {module_name}")
print(f"Import time: {elapsed:.4f}s")
print(f"Dependencies loaded: {after - before}")
# Test various modules
measure_import_size("math") # Fast, minimal dependencies
measure_import_size("json") # Medium
measure_import_size("requests") # Slower, many dependenciesSometimes you need to reload a module (mainly for development).
import importlib
import mymodule
# Make changes to mymodule.py...
# Reload the module
importlib.reload(mymodule)
# Now mymodule has the new codeā ļø Warning: Reloading is tricky! Existing references aren't updated.
import importlib
import mymodule
# Old reference
old_func = mymodule.my_function
# Reload
importlib.reload(mymodule)
# This points to new version
new_func = mymodule.my_function
# But old_func still points to old version!
old_func == new_func # FalseWeb Application Startup:
# ā Slow startup
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_cors import CORS
from celery import Celery
import redis
import numpy as np
import pandas as pd
app = Flask(__name__)
db = SQLAlchemy(app)
CORS(app)
celery = Celery(app)
redis_client = redis.Redis()
@app.route("/health")
def health():
return {"status": "ok"}# ā
Fast startup - lazy imports
from flask import Flask
app = Flask(__name__)
@app.route("/health")
def health():
return {"status": "ok"}
@app.route("/data")
def get_data():
# Import heavy packages only when needed
from flask_sqlalchemy import SQLAlchemy
import pandas as pd
db = SQLAlchemy(app)
data = pd.read_csv("data.csv")
return data.to_json()Circular imports can slow down module loading.
# ā Circular imports
# models.py
from . import views
# views.py
from . import models # Circular!
# ā
Solution 1: Import inside function
# models.py
class User:
def render(self):
from . import views # Import when needed
return views.render_user(self)
# ā
Solution 2: Import at end of module
# models.py
from . import views # Import at endReady to practice? Challenges | Quiz
Resources
Ojasa Mirai
Master AI-powered development skills through structured learning, real projects, and verified credentials. Whether you're upskilling your team or launching your career, we deliver the skills companies actually need.
Learn Deep ⢠Build Real ⢠Verify Skills ⢠Launch Forward