Skip to content
Foxipa

Suggest an edit

Tell us what should be corrected, clarified, or improved. Submission will be connected to Foxipa’s contribution service later.

No information is sent anywhere yet. Your suggestion is only prepared in your browser.

Learning

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.

Levels: Beginner ~18 min read

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.

text project tree
shop/
    __init__.py
    pricing.py
    reports.py

A 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.

python shop/__init__.py
# shop/__init__.py
package_name = "Shop"

The simplest __init__.py can be empty. It may also define names for the package namespace.

python main.py
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.

python shop/pricing.py
# shop/pricing.py
def total_with_tax(amount):
    return amount * 1.14

The pricing module owns its function.

python main.py
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(...).

python main.py
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.

python shop/reports.py
# 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.

text nested package
shop/
    __init__.py
    reports/
        __init__.py
        daily.py

Subpackages 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.

python main.py
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.

Was this page helpful?

Mark this learning resource complete to track your learning progress.