Python is a great language with a beautiful syntax, lots of useful libraries and great community.
Unfortunately, one of the things I like less is the way imports work.
In almost every large Python project I do, I want to centralise a set of shared services that all submodules could use. Example of this is having a module with a (static) function that initialises connections to databases and fetches the credentials by itself. This is unfortunately always a pain as it has to be in a folder shared by all modules.
I have thus came up with the easiest way to deal with the issue of python imports and that is by appending the module paths to the system path.
Let’s imagine the following scenario in our project structure:
We have a project named demo with a few Python files (.py) files which are officially called modules. Our main code is in the import_demo.py module and we want to import other modules.
You can find the exact folder structure and the whole code for the demo at this Github repository.
Specific scenarios of possible imports are:
— please note that in all of these examples we are running the script import_demo.py with a simple command and that we are running it inside package1 directory. The directory from where a script is executed is very important when determining how module imports will behave.
1. Importing from a module in the same directory
This is the easiest import to do:
import module_to_be_imported_same module_to_be_imported_same.Demo()
2. Importing from a module in a sub-directory
This one is quite easy and native as well:
from package3 import module_to_be_imported_sub module_to_be_imported_sub.Demo()
3. Importing from a module in a parent directory
import sys sys.path.append('..') import module_to_be_imported_parent module_to_be_imported_parent.Demo()
4. Importing from a module at the same level but in a different directory
import sys sys.path.append('../package2') import module_to_be_imported_cross module_to_be_imported_cross.Demo()
I really hate that Python is not that intuitive (for someone with a Java background) when you want to share a single module across various other modules.
I come across this very often when maintaining a codebase of data pipelines (Python scripts – modules). Often logic is not shared between modules and stuff is rewritten at every single place which is a very bad practice.
Reminder, you can see the exact code and the whole setup at this repository.
If you have a better approach, I’d love to hear your approach in Python 3+ environments.