This guide explains creating packages with __init__.py through a focused Python example. You will learn the behavior to expect, why it matters in a real program, and how to recognize the common mistakes before applying it in your own project.
What You Will Learn
A regular Python package is a directory containing __init__.py. The file may be empty, but it marks a package and can intentionally expose selected package-level names.
When and Why to Use It
The following example focuses on a practical use of Creating Packages with __init__.py.
Step-by-Step Example
from pathlib import Path
from tempfile import TemporaryDirectory
with TemporaryDirectory() as directory:
package_folder = Path(directory) / "shop"
package_folder.mkdir()
(package_folder / "__init__.py").write_text("", encoding="utf-8")
(package_folder / "prices.py").write_text("tax_rate = 0.1\n", encoding="utf-8")
print(sorted(path.name for path in package_folder.iterdir()))
Understanding the Example
The output lists __init__.py and prices.py. With the project root importable, shop.prices is a normal submodule.
Expected Output
['__init__.py', 'prices.py']
Important Behavior and Edge Cases
Putting expensive or side-effecting work in __init__.py can run unexpectedly during package imports.
Try It Yourself
Make a utils package with text.py and an empty __init__.py.
Common Beginner Mistakes
- Putting expensive or side-effecting work in __init__.py can run unexpectedly during package imports.
- Assuming that an import has no initialization effects or that every environment resolves modules in the same way.
- Skipping the practice step and assuming the example covers every input. Test at least one normal case and one edge case relevant to this topic.
Key Takeaways
- A regular Python package is a directory containing __init__.py.
- The output lists __init__.py and prices.py.
- Apply the technique deliberately, checking its documented input requirements and failure behavior before integrating it into a larger project.