I have a python (3.6.3) project which has the following structure
setup.py
utils #python package
utils/constants.py
utils/name_reports.py
normalization #python package
normalization/resolve_name.py
categorization #python package
categorization/animal_categories.py
You can find the source code here on github - https://github.com/techmango-org/python-import-resolution
Here is the source code for utils/name_reports.py
import normalization.resolve_name as rn
import categorization.animal_categories as ac
test_name = 'DOGY'
resolved_name = rn.get_animal_name(test_name)
print('********ANIMAL CATEGORY IS:', ac.get_animal_score(resolved_name))
When I run python utils/name_reports.py
I am getting the following exception
Traceback (most recent call last):
File "utils/name_reports.py", line 1, in <module>
import normalization.resolve_name as rn
ModuleNotFoundError: No module named 'normalization'
I have tried to solve this problem by installing the current package into virtual env site packages by running pip install .
but that means for every local change I have to run pip install --upgrade .
to move my local changes into site packages.
I have been using a hack -m unittest
to get this problem solved. Check this screenshot
But I am unable to understand what difference does it create. Here are the exact questions -
-m unittest
is creating which is solving this issue?Since there are already many answers on SO for this*, I will focus on question (2). About what is a better code organization:
|- setup.py
|- top_pkg_name
|- __init__.py
|- pkg1
|- __init__.py
|- pkg2
|- __init__.py
The (relative) import is done as follows, from inside module_2
:
from ..pkg1 import module1 as m1
Alternatively, you can use absolute imports, which refer to the top package name:
from top_pkg_name.pkg1 import module1 as m1
In such an organization, when you want to run any module as a script, you have to use the -m
flag:
python -m top_pkg_name.pkg1.module1
For question (3), I'm not sure but it looks like the unittest
module adds the folder to path, allowing the imports to happen directly.
*Refer: