I am writing a web app using python3, venv and c9.io PAAS. I have the following structure of my code:
batch_runner.py
logic/
__init__.py
parsers/
__init__.py
time_parser.py
abstract_parser.py
here batch_runner
imports abstract_parser
, which, in it turn, import from time_parser. everything was installed and runs with venv activated.
To be specific, batch_runner.py
contains:
from logic.parsers import abstract
from sys import argv
url = argv[1]
a = abstract(url)
logic/__init__.py
is empty. logic/parsers/__init__.py
contains:
from abstract_parser import abstract
from time_parser import _timeInfo
If I go to logic
and run python abstract_parser.py
directly, everything works as expected. However, if I go one level up, and run python batch_runner.py
, it is able to import abstract_parser
, but it can't find time_parser
which is called from abstract_parser
, throwing ImportError: No module named 'abstract'
Do read about importing from the python documentation on modules.
In this case, one possible solution is to use relative imports inside your package:
That is, in logic/parsers/__init__.py
, use:
from .abstract_parser import abstract
from .time_parser import _timeInfo
and in abstract_parser.py
:
from .time_parser import _timeInfo
This should let parsers/__init__.py
find the abstract_parser
module and the time_parser
module.
The python import system has a surprising number of traps that you can fall into. This blog post by Nick Coghlan describes many of them, and I personally consider it a must-read if you're planning to develop a package.