Python Packages and Imports
Learn how Python organizes related modules into packages, how __init__.py participates in regular packages, and how absolute and relative imports connect modules.
Basic
A single module works well for a small amount of reusable code. As a project grows, you may want several related modules to live under one importable name. Python uses
packages to organize modules with dotted names such as
shop.pricing.
A package groups related modules
A regular package is typically a directory containing
__init__.py. Inside that directory you can place ordinary Python modules. The package name becomes the first part of an import path, and a module inside it adds another part.
shop/
__init__.py
pricing.py
reports.pyA simple regular package: the directory is the package, and its Python files are modules inside it.
With this structure,
shop is the package, while
shop.pricing and
shop.reports are module names.
What __init__.py does
For a regular package,
__init__.py is the package initialization module. It can be empty, or it can contain Python code that should run when the package is imported. It also gives the package its own namespace.
# shop/__init__.py
package_name = "Shop"The simplest __init__.py can be empty. It may also define names for the package namespace.
import shop
print(shop.package_name)Importing the package makes its package namespace available through the package name.
Import a module inside a package
Use the full dotted module name when you want the module itself. After
import shop.pricing, you can access names through
shop.pricing.
# shop/pricing.py
def total_with_tax(amount):
return amount * 1.14The pricing module owns its function.
import shop.pricing
print(shop.pricing.total_with_tax(100))The package name and module name form a dotted import path.
Import a submodule with from
You can also write
from shop import pricing. This imports the submodule and binds the name
pricing in the importing module. You can then call
pricing.total_with_tax(...).
from shop import pricing
print(pricing.total_with_tax(100))This form keeps the package prefix out of later uses while still making the module name visible.
Absolute and relative imports
Inside a package, an
absolute import names the package from the top level, such as
from shop import pricing. A
relative import starts with dots and refers to the current package or one of its parents.
# shop/reports.py
from . import pricing
def total(amount):
return pricing.total_with_tax(amount)A single dot means the current package. The reports module can use another module in the same package.
Relative imports are useful for modules that belong to a package. A main module does not have a package, so code intended to run as the top-level module should use absolute imports instead.
Subpackages use more dots
Packages can contain subpackages. For example,
shop.reports.daily can identify a module named
daily inside the
reports subpackage of
shop. Each dotted part represents another package or, at the end, a module.
shop/
__init__.py
reports/
__init__.py
daily.pySubpackages let a larger project organize modules into deeper groups.
Namespace packages are an advanced case
Python also supports
namespace packages, which can span multiple locations and do not use an ordinary
__init__.py file. This is useful for advanced packaging scenarios, but it is not required for learning ordinary package structure.
Choose an import that shows the structure
A good package import makes the relationship between the package and its modules easy to read. Use a full absolute import when it makes ownership clearer, and use a relative import when a module is deliberately referring to another module inside its own package.
from shop import pricing
amount = pricing.total_with_tax(50)
print(amount)A clear import keeps the module name visible at the point where it is used.
What comes next
This lesson stops before
sys.path, import hooks, finders and loaders,
importlib, and circular-import internals. Those are deeper import-system topics and should not be mixed into the first package lesson.
Thanks for your feedback.
Mark this learning resource complete to track your learning progress.