Modules and Packages
|
This section documents the current Python release line as published at the official Python documentation, which is the reference these pages are written and verified against. No specific patch version is pinned. This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production. This section’s bibliography lists the reference material consulted while preparing these pages. |
A module is simply a .py file; a package is a directory of modules. Splitting code this way lets it be
reused across scripts and projects, as covered in the tutorial’s
Modules chapter.
Importing Modules
import name runs the module’s top-level code once and binds the module object itself — its functions,
classes, and variables are then reached as attributes:
import math
math.sqrt(16) # 4.0
math.pi # 3.141592653589793
from module import name binds specific names directly into the current namespace, skipping the module-object
prefix; import module as alias renames the bound module object:
from math import sqrt, pi
sqrt(16) # 4.0 -- no 'math.' prefix needed
pi # 3.141592653589793
import numpy as np # conventional alias
A module is a first-class object: attributes can be listed and introspected like any other object’s:
import math
type(math) # <class 'module'>
"sqrt" in dir(math) # True
math.__name__ # 'math'
The name == "main" Pattern
Every module has a name attribute. When a file is run directly, Python sets name to
"main"; when the same file is imported, name is set to the module’s own name instead. Guarding
script-only code behind this check lets one file work both as an importable module and a runnable script:
# greetings.py
def greet(name: str) -> str:
return f"Hello, {name}!"
def main() -> None:
print(greet("world"))
if __name__ == "__main__":
main() # runs only when executed as `python greetings.py`
$ python greetings.py
Hello, world!
Importing the same file elsewhere runs the function definitions but skips main(), since name is then
"greetings", not "main":
import greetings
greetings.greet("Ada") # 'Hello, Ada!' -- main() never ran
Packages
A package is a directory containing an init.py file (which may be empty) alongside its modules;
init.py marks the directory as importable and runs once, the first time the package is imported. Packages
can nest arbitrarily to form subpackages, as shown under
Packages in the tutorial:
shapes/
├── __init__.py
├── circle.py
├── square.py
└── solids/
├── __init__.py
└── sphere.py
From outside the package, import a submodule with dotted syntax:
from shapes import circle
from shapes.solids import sphere
circle.Circle(radius=2)
sphere.Sphere(radius=1)
Relative imports, valid only inside a package’s own modules, reference siblings by leading dots — one dot for the current package, two for the parent:
# shapes/square.py
from . import circle # sibling module in the same package
from .circle import Circle # a specific name from a sibling module
The Module Search Path
import does not scan the whole filesystem — it searches sys.path, a list built from the script’s own
directory, the PYTHONPATH environment variable, and installation-dependent defaults:
import sys
sys.path
# ['', '/usr/lib/python3.13', '/usr/lib/python3.13/site-packages', ...]
$ PYTHONPATH=/opt/mylibs python app.py
Once found, the module’s source is compiled to bytecode and cached under pycache/.pyc; a later import
reuses that cache unless the source file is newer, and either way the module body executes *only once per
process — a second import of the same name just returns the cached module object without re-running it:
import time
import config # first import: module body executes, printed side effects appear
import config # second import: cached module object returned, nothing re-executed
A circular import — module a importing b while b imports a — fails or yields a half-initialized
module, because the first import is still running when the second one starts. Avoid it by importing the
specific name inside the function that needs it (a local import) rather than at module top level, or by
restructuring the shared code into a third module both sides import from.
How import Resolves a Name
The exact algorithm — finders, loaders, and the sys.modules cache — is specified in the
import system reference; the tutorial’s
Modules chapter and its
Packages section cover the everyday usage above.
See Also
-
Virtual Environments and Packaging — installing third-party packages into
sys.pathand isolating dependencies per project. -
Standard Library Tour — a tour of the modules the standard library ships, ready to
importwithout installing anything.