Creating your own packages
As Python programs grow, single files stop being enough. We start to collect related functions, types, and helpers that naturally belong together. Python packages exist to support this kind of structure, and they matter because they let us reuse code cleanly across multiple programs, including larger AI-capable systems that evolve over time.
Organizing Python code as a package
A Python package is a directory that groups related modules under a single name. Instead of thinking in terms of individual .py files, we begin to think in terms of cohesive units of functionality.
This organization helps us reason about code ownership, responsibilities, and reuse. It also makes our programs easier to extend without turning into a single, tangled file.
Creating a package directory structure
A package starts as a directory, not a file. Inside that directory, we place one or more Python modules that belong together.
A simple structure might look like this:
sitegen/
pages.py
bodies.py
At this point, the directory exists, but Python does not yet treat it as a package. That behavior is defined explicitly.
Importing modules from a custom package
Once code is organized into a package, we import from it using the package name. This allows one program to rely on shared functionality without copying code.
For example, if we have a function that renders a simple HTML page, we can import it directly from the package:
from sitegen.pages import render_page
html = render_page("Mars")
This makes it clear where the functionality lives and encourages reuse across multiple scripts or tools.
Using __init__.py to define package behavior
The presence of a file named __init__.py tells Python that a directory is a package. This file can be empty, or it can define what the package exposes to the outside world.
A minimal __init__.py might re-export selected functions or classes:
from .pages import render_page
This allows consumers to write simpler imports while keeping the internal structure flexible.
Reusing code across multiple programs
Once a package exists, it can be imported by any Python program that can see it. This is how shared logic becomes a stable building block rather than a one-off script.
In practice, this means the same package might generate HTML pages in one program and support batch processing in another, without duplication. The package becomes a reusable unit of behavior rather than just a folder of files.
Conclusion
We now understand how Python packages group related code, how they are structured on disk, and how they are imported and reused. With this mental model in place, organizing growing programs into clear, reusable components becomes a natural next step.