If you have to import a directory structure, you should make each directory a module by creating an __init__.py file in them, and use relative import statements. I usually have one main.py as the entry point, which imports a lib module that contains all of the program logic.
├── lib
│ ├── __init__.py
│ ├── module_content.py
│ └── submodule
│ ├── __init__.py
│ └── submodule_content.py
└── main.py
You can import the lib directory as a module:
main.py:
from lib import some_fn
Within any module, though, you should use relative import statements to import from files and submodules, and regular import statements to import packages from the system or the venv:
lib/__init__.py:
from .module_content import some_fn # import from a file
from .submodule import some_other_fn # import from a submodule directory
from os.path import join # import from an installed package
Items that you define in __init__.py or import into it will be available to import from the module: from .submodule import some_fn. Otherwise, you can import an item from a file by specifying the full path: from .submodule.submodule_content import some_fn.
You can also import an item from a parent package using the .. prefix: from ..some_other_submodule import some_fn.