4

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?

asked Sep 4, 2017 at 10:41
1
  • 1
    Or you can add the parent directory of foo to sys.path Commented Sep 4, 2017 at 10:57

1 Answer 1

2

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.

answered Sep 4, 2017 at 10:51
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks @ray that solves the issue. I have a quick follow up: What I'm actually trying to do is write a small command line tool for natural language processing. In this use case, first_module is intended to be the script which accesses all the back-end function. Does this mean that, by design, I have to put the script outside the package?
@buechel Not really. You can always add a sub-directory with the same name as the top-level directory, but I'd (personally) avoid having something like foo/foo layout. Instead, just be mindful of the import lines in the top-level module.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.