Modules, Imports, and Packages
Split Python code into cohesive modules, understand import execution and name resolution, and organize a small package without circular dependencies.
Before this lesson
Explain what import executes
Design cohesive module boundaries
Prevent common circular imports
The short answer
A module is an importable Python file; a package groups modules under a namespace. Put related behavior together, expose a narrow public surface, use absolute imports inside applications, and keep dependency direction acyclic.
Build the mental model
On first import, Python locates a module, creates its namespace, executes its top-level statements, and caches the module object in sys.modules. Later imports in the same process generally reuse that object.
The central idea in this lesson is module boundaries. Read the rule, predict a concrete outcome, and then run the smallest example that can confirm or reject the prediction. This separates knowledge from familiarity with syntax.
Make the design choice explicit
Move pure domain rules into modules that do not import console or file adapters. Let the entry point depend on those rules. Use from module import name sparingly when origin remains obvious, and never use wildcard imports in application code.
from statistics import mean
def summarize(values):
return {"count": len(values), "average": mean(values)}
if __name__ == "__main__":
result = summarize([8, 10, 12])
print(f"{result['count']} values, average {result['average']:.1f}")Expected output
3 values, average 10.0
Trace the example before running it. Identify each input, transformation, returned value, and side effect. Then change one boundary value and explain why the new behavior follows from the rule rather than memorizing the output.
Recognize failure modes
Circular imports often indicate tangled responsibilities. Extract shared concepts into a lower-level module or invert a dependency. Keep expensive work and user interaction out of module top level so importing remains predictable and testable.
Use a professional practice loop
Turn the concept into a repeatable workflow: write down the expected behavior, implement one coherent change, run a representative example, and retain a regression check. If the result surprises you, capture the exact input and error before changing anything.
Review the program for names, boundaries, and hidden side effects. A solution is complete when another developer can understand its contract, reproduce its setup, and verify both the successful path and one meaningful failure path.
Quick knowledge check
Answer before you reveal.
01Why avoid user input at module top level?
Importing the module would unexpectedly block or perform work, making reuse and testing difficult.
02What four steps make the practice loop reliable?
Predict the behavior, make one coherent change, run it, and retain a check that detects regression.
Exercise
Practice challenge
Sketch a three-module reading tracker with models, calculations, and a command-line entry point; document which direction each import should flow.
Requirements
- The successful path produces the documented result
- At least one boundary or invalid case is handled deliberately
- Calculation or domain logic is separated from console interaction
Optional extension: Add one automated regression check for the most important rule.
Open in Python compilerLesson checkpoint
One small step locks it in
Mark this lesson complete, then keep the momentum going.
Clear up the details
Frequently asked questions
Is module boundaries only important in large programs?
No. Small programs reveal the same rules with less noise, and learning the rule early prevents fragile habits from becoming architecture.
Should I memorize every API used here?
No. Memorize the mental model and how to verify behavior. Use documentation for exact names and parameters when needed.
How do I know the exercise is finished?
Meet every success criterion, test at least one boundary or failure case, and explain why the output follows from the code.