Fundamentals 11 min read

Understanding Python import: absolute vs. relative imports and common pitfalls

This article explains Python's import system, covering absolute and relative import syntax, package structure, execution contexts, and typical errors, while providing clear code examples and practical guidelines for correctly organizing and running modules.

Python Programming Learning Circle
Python Programming Learning Circle
Python Programming Learning Circle
Understanding Python import: absolute vs. relative imports and common pitfalls

The author, after two years of using Python, finally demystifies the import statement, which had previously been a source of confusion.

Referencing a Taiwanese blog post and PEP 328, the article outlines the purpose of import : to load other Python files (modules) so their classes, functions, or variables can be reused, recommending Python 3 for consistency.

First, a simple project structure Tree with m1.py and m2.py is created. m1.py contains:

<code>import os
import m2
m2.printSelf()</code>

and m2.py defines:

<code>def printSelf():
    print('In m2')</code>

Running python m1.py prints In m2 , demonstrating the basic form import module_name . Python searches sys.path and the script's directory for the module.

The article warns against using this form to import files from the same directory in larger projects, introducing the second form from package_name import module_name . A sub‑directory Branch with m3.py is added, and m1.py is changed to:

<code>from Branch import m3
m3.printSelf()</code>

This illustrates package imports and the concept of a package.

To show why the first form can fail, Branch/m4.py is created and imported inside m3.py with import m4 . Running m1.py now raises ModuleNotFoundError because m4.py is not in sys.path relative to the entry script.

The difference between absolute and relative imports in Python 2 vs. Python 3 is explained: in Python 3, the two forms become absolute imports, and modules that are not the entry script should use relative imports such as from . import m4 .

A list of relative‑import syntaxes is provided:

from . import module_name

from .package_name import module_name

from .. import module_name

from ..package_name import module_name

and further dot prefixes for higher levels

The article clarifies that an entry script can use relative imports only when executed with the -m flag (e.g., python -m Tree.m1 ), because this treats the script as a module within a package.

It also revisits the if __name__ == '__main__': idiom, explaining how __name__ is set to __main__ for direct execution and to the module name when imported.

Running python m1.py with a relative import like from .Branch import m3 fails with ModuleNotFoundError , while python -m Tree.m1 works because the interpreter knows the package hierarchy.

Additional useful import forms are listed: aliasing ( import module_name as alias ), selective imports ( from module_name import func, var, Class ), and line‑continuation techniques using backslashes or parentheses.

Finally, a common error ValueError: attempted relative import beyond top-level package is demonstrated with a four‑file example, and the solution is to convert all imports to relative form and run the entry script with python -m Tree.m1 .

Module@Importpackagerelative importabsolute importPEP 328
Python Programming Learning Circle
Written by

Python Programming Learning Circle

A global community of Chinese Python developers offering technical articles, columns, original video tutorials, and problem sets. Topics include web full‑stack development, web scraping, data analysis, natural language processing, image processing, machine learning, automated testing, DevOps automation, and big data.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.