How can I do relative imports in Python?
Execute a relative import with the prefix .
for same-level modules or ..
for a parent-level module in a package. Use them in your Python code like:
Or to import from a parent package:
Ensure you're inside a package and not running the script as __main__
for these relative imports to work.
Unlocking the 'Attempted relative import in non-package' mythical riddle
The mysterious error "Attempted relative import in non-package" visits those who dare to perform a relative import from a module deemed as __main__
. It feasts on empty __init__.py
files or attempts to import from a script ran directly, leaving behind a trail of confusion and unanswered StackOverflow questions. Remember, Python recognizes directories as packages if they contain an __init__.py
file.
The 'python -m' spell
To run a module within a package without angering the Python gods, invoke the python -m
spell in the command line. This charm tells Python to run the module as a script, enabling successful relative imports like a smooth operator:
This is the prophesized way to avoid errors related to running a module as __main__
.
Invoking PEP 366
In some ancient scripts, it is told of the PEP 366, a mystical guideline that enables executing a module inside a package as if it were run with the -m
switch. This works by setting the __package__
attribute — a viable option for dealing with stubborn legacy codebases.
The secret life of the module's __name__
With relative imports, the module's __name__
changes, affecting the module's position within the package. If you run a script directly, its __name__
changes to __main__
, complicating relative imports. Hence, the deception of -m
, which makes Python think it's a script and not __main__
.
Captain's guide to organising your package
Ensuring a healthy package structure can be more effective than a daily apple for keeping import headaches away. Avoid filling your package directories with scripts you'll be running directly. Rather, let a main.py
reside outside your packages, taking charge of coordinating the imports and running the show. Your imports will thank you.
How to catch an ImportError
Embrace your inner catcher and catch ImportError gracefully. You do that by wrapping relative imports in try-except blocks. If you catch an ImportError
, you can provide helpful feedback or fall back to an absolute import, if necessary. This way, even failing is done in style.
The clean imports mantra
And finally, to keep the house (okay, the namespace) clean, resist the seductive pull of "from module import *". Explicit is better than implicit, remember? Namespace pollution isn't a fun party. Keep your imports explicit and your code easy to maintain.
Was this article helpful?