Field notes
Python Lazy Imports: From Function-Level Imports to Python 3.15
How lazy imports defer loading heavy libraries like torch and pandas until first use, cutting startup latency and memory usage.
What are lazy imports?
Lazy import means Python does not load a module immediately at startup; it loads it only when you first use it. This significantly reduces process startup time and memory footprint, especially for heavy libraries like torch, pandas, cv2, or tensorflow.
The Python 3.15 lazy syntax
Python 3.15 introduced the dedicated lazy keyword to make deferred loading first-class at the language level:
lazy import torch
def train_model():
# torch is loaded only when this line first runs
model = torch.nn.Linear(10, 1)
You can also use it with from ... import:
lazy from pandas import DataFrame
def make_df():
# pandas loads here, not at program startup
return DataFrame({"a": [1, 2]})
The import statement stays at the top of the file following standard code style, but the module is only loaded on first access to the imported name.
How it works in Python 3.14 and earlier
If you are running Python 3.14 or earlier, the standard practical pattern is placing the import inside the function or method that requires it:
def process_video():
import cv2 # imported only when this function is called
cap = cv2.VideoCapture("video.mp4")
return cap
Because Python caches loaded modules in sys.modules, the import overhead is incurred once during the first invocation. Subsequent calls retrieve the cached module with minimal lookup cost.
When to use lazy imports
Lazy imports are especially valuable when:
- Heavy dependencies: The library is large and slow to import (such as machine learning, computer vision, or scientific packages).
- Optional features: A dependency is only needed for one specific feature or edge case.
- Fast startup requirements: You need sub-second CLI responsiveness or lightweight API worker boots.
- Selective code paths: You want to avoid paying an import penalty for users or workers that never touch that specific execution branch.
Example in a FastAPI service
In an API with many endpoints, not every route needs heavy ML models loaded into memory upfront:
from fastapi import FastAPI
app = FastAPI()
@app.post("/analyze")
def analyze():
import torch # loaded only when /analyze is called
# ... run inference ...
return {"status": "complete"}
Cautions and considerations
- Deferred errors: Any
ImportErrormoves from startup time to first use, which means missing dependencies or syntax errors can appear later and during active user requests. - Clarity first: Avoid lazy imports for small, core utility modules that are always used; standard top-level imports remain the cleanest default.
- Scope limitations in 3.15: In Python 3.15,
lazyimports are only permitted at module scope—not inside functions, classes, ortryblocks.
For most production systems today, function-level imports remain the standard approach for heavy or optional modules; adopt Python 3.15's native lazy import once your runtime environment supports it.