C.W.K.
Stream
Lesson 01 of 05 · published

import — How Python Finds and Loads Code

~22 min · import, module, sys.path, package

Level 0Curious
0 XP0/93 lessons0/23 achievements
0/100 XP to next level100 XP to go0% complete

What import really does

When you write import json, Python searches the directories in sys.path in order, finds a file or directory named json, executes its body once (caching the result in sys.modules), and binds the name json in your namespace. Subsequent import json calls are just dict lookups — the body doesn't run again.

The four import forms

import x — bind name x. import x.y — bind x; access x.y. from x import y — bind y (x is loaded but not bound). from x import y as z — bind z. The from form looks for y as either a sub-module or an attribute of x.

Absolute vs relative imports

Absolute imports use the full path: from mypackage.subpkg import mod. Relative imports use dots: from . import sibling (same package), from .. import parent_sibling (parent's sibling). Modern Python style: prefer absolute imports, except when shipping a package and importing from within it where relative imports avoid the "rename the package and break" problem.

The from x import * trap

from x import * imports everything x exposes (controlled by __all__ or fallback to public names). It pollutes the namespace and makes "where did this name come from?" hard to answer. Reserve it for REPL convenience and the rare case of a tightly-scoped wildcard re-export.

Principle: Imports are statements. They have side effects (executing the imported module). Putting all imports at the top of a file makes those side effects predictable. Hidden imports inside functions are a code smell unless there's a specific reason (avoiding a circular import, deferring an expensive load).

Code

The four forms — and what each binds·python
# Form 1 — bind the module
import json
print(json.dumps({"a": 1}))

# Form 2 — bind the top-level package, access submodule via dots
import os.path
print(os.path.join("a", "b"))     # 'os' is bound

# Form 3 — bind a name from a module
from datetime import datetime
print(datetime.now())

# Form 4 — rename on import
import numpy as np                # very common alias
import pandas as pd
How Python finds a module — sys.path·python
import sys
for p in sys.path:
    print(p)
# Typical contents:
# 1. The script's directory (or '' if interactive)
# 2. Directories in PYTHONPATH env var
# 3. Standard library directories
# 4. site-packages

# To inspect a loaded module's location
import json
print(json.__file__)               # /path/to/lib/python3.x/json/__init__.py
Cached imports — body runs once·python
# /tmp/loud.py
# print("loud module loading")
# value = 42

import sys
sys.path.insert(0, "/tmp")

import loud                       # 'loud module loading' prints once
import loud                       # nothing — already cached in sys.modules
print(loud.value)                 # 42

# To force a reload
import importlib
importlib.reload(loud)            # 'loud module loading' prints again
Relative imports — within a package·python
# Imagine this package structure:
# mypackage/
#   __init__.py
#   core.py
#   utils.py
#   sub/
#     __init__.py
#     helper.py

# Inside mypackage/utils.py
# from .core import important_thing       # same level — same package
# from . import core                       # same level — module reference

# Inside mypackage/sub/helper.py
# from ..core import important_thing       # one level up
# from .. import utils                     # parent's sibling

# Relative imports only work in packages — modules at the top level
# can't use them.

External links

Exercise

Create a directory /tmp/quest_pkg/ with __init__.py (empty) and three modules: a.py (defines x = 1), b.py (does from .a import x; prints x*2), and c.py (does from quest_pkg.a import x). Add /tmp to sys.path and import each. Confirm that the relative import in b and the absolute in c give the same result.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.