I feel that this is a rather basic issue, so I'm only more upset that I wasn't able to fix it for quite some time. Say I have the following folder structure:
foo
|- first_module.py
|- __init__.py
|- bar
|- second_module.py
|- __init__.py
foo and bar being directories. In first_module.py I have an absolute import statement referring to second_module.py:
import foo.bar.second_module
Now, if run first_module.py as a script (foo being the working directory), I get this error
ModuleNotFoundError: No module named 'foo':
Please, can anyone explain to me why this is the case? I've checked that foo is in sys.path. I've read the docs and a bunch of other stackoverflow posts. I think it might have to do with the interpreter not knowing that first_module.py is part of the package foo. But how can I fix this?
-
1Or you can add the parent directory of foo to sys.pathphilippd– philippd2017年09月04日 10:57:47 +00:00Commented Sep 4, 2017 at 10:57
1 Answer 1
The problem is that trying import foo.bar.second_module would require that your directory structure have a foo directory as a child of your current working directory, i.e.:
foo
|- first_module.py
|- __init__.py
|- foo
|- bar
|- second_module.py <-- at foo.bar.second_module
|- __init__.py
To keep your original directory structure and import successfully, simply change your first_module to use import bar.second_module instead.
why this is the case?
When importing, you should think of the dots . as analogous to path separators. Thus, using the following sample layout:
foo
|- first.py
|- bar
|- second.py
|- third.py
If you want to import module second.py from first.py, you must write import bar.second. If you want to import third from second, you can write import third because they're both in the same directory.
Note that you'd still need to write import bar.third if trying to import from first.
2 Comments
foo/foo layout. Instead, just be mindful of the import lines in the top-level module.