There are sometimes when you want to run a python script
from a package directly, and you may encounter “ImportError: No module named X”
error. This blog shares why and how to solve it.
Example:
vagrant@stock:/stock/test_python$
tree .
.
├── p0.py
└── pack1
├── __init__.py
├── p1.py
├── p2.py
vagrant@stock:/stock/test_python$
cat p0.py
print("this is p0")
import pack1.p1
vagrant@stock:/stock/test_python$
cat ./pack1/p1.py
print("this is p1")
import pack1.p2
vagrant@stock:/stock/test_python$
cat ./pack1/p2.py
print("this is p2")
Running p0.py
is ok:
vagrant@stock:/stock/test_python$
python ./p0.py
this is p0
this is p1
this is p2
But if you want to run p1.py directly, you will run into the
import error:
vagrant@stock:/stock/test_python$
python ./pack1/p1.py
this is p1
Traceback (most recent call last):
File
"./pack1/p1.py", line 7, in <module>
import pack1.p2
ImportError: No module named 'pack1'
To find out why, we can print python runtime’s path, adding
the highlighted into ./pack1/p1.py:
vagrant@stock:/stock/test_python$
cat ./pack1/p1.py
import
sys
print('\n'.join(sys.path))
print("this is p1")
And rerun it:
vagrant@stock:/stock/test_python$
python ./pack1/p1.py
/stock/test_python/pack1
/home/vagrant/anaconda3/lib/python3.5
…
this is p1
Traceback (most recent call last):
File "./pack1/p1.py", line 7, in
<module>
import pack1.p2
ImportError: No module named 'pack1'
You can see Python add the directory where the script being
run is under to the runtime paths, there is no /stock/test_python/pack1/pack1/p1.py,
and the error is thrown out.
To solve this problem, export the current directory:
vagrant@stock:/stock/test_python$
export PYTHONPATH='.'
vagrant@stock:/stock/test_python$
python ./pack1/p1.py
/stock/test_python/pack1
/stock/test_python
/home/vagrant/anaconda3/lib/python3.5
…
this is p1
this is p2