Use relative imports inside a Python package

Import sibling and parent-package modules with leading dots, run package modules with -m, and avoid confusing package hierarchy with filesystem paths.

Best practices
Python programming and application logging

A leading dot in an import refers to the current package. Two dots move to its parent package; additional dots move up further. The operation depends on package context, not simply where a file sits on disk.

Start with a package structure

my_package/
    __init__.py
    module1.py
    module2.py
    subpackage/
        __init__.py
        submodule1.py

Inside module1.py, these imports refer to modules or objects within the package:

from . import module2
from .module2 import some_function
from .subpackage import submodule1
from .subpackage.submodule1 import func

The named functions must actually be defined in the target modules. Inside subpackage/submodule1.py, parent-package imports can be:

from .. import module2
from ..module2 import helper

Avoid making module1 and submodule1 import each other's incompletely initialized attributes. Relative imports do not prevent circular-import problems.

Run the module in its package context

From the directory containing my_package, use:

python -m my_package.module1

Running python my_package/module1.py ordinarily gives that file no known parent package and makes its explicit relative imports fail. -m uses the import machinery to establish module/package context. The package still needs to be discoverable on the interpreter's import path.

Choose between relative and absolute imports

from my_package.module2 import some_function
from .module2 import some_function

These can refer to the same object when used from the appropriate package. Absolute imports state the complete package path; explicit relative imports can keep internal references concise when a package is renamed or moved. Follow a consistent project convention rather than changing import style to hide a packaging problem.

FAQ

Can I keep adding dots to reach any directory? No. You cannot import beyond the top-level package by adding more dots. A sibling directory on disk is not automatically a sibling package in the current import context.

Why does the IDE disagree with the command line? Compare the selected interpreter, installed package, working directory, and import/search paths. Marking a source root can help an IDE analyze the project, but it does not itself package or install the application for command-line use.

Is init.py required? Regular packages use it and can run initialization code there. Namespace packages, supported since Python 3.3, can omit it under their own packaging rules. Do not add or remove it indiscriminately in a namespace-package project.

References

Get a tailored plan

Contact us

Join the community

Scan with WeChat
to join the community

Try Guance

Start online and pay only for what you use.

Get started

Choose a Guance plan

Code hosting