I am new to Python. This really confused me!
My directory structure is like this:
Project
| - subpackage1
|- a.py
| - subpackage2
|- b.py
| - c.py
When I import a.py
into b.py
with from subpackage1 import a
, I get a ModuleNotFoundError. It seems like I cannot import a file from the parent directory.
Some solutions suggest to add an empty file __init__.py
in each directory, but that does not work. As a work around, I have put the following in each subfile (i.e., a.py
and b.py
) to access the parent directory:
import os
import sys
sys.path.append(os.path.abspath('..'))
I have tried to output sys.path
in subfiles, it only includes the current file path and anaconda path, so I have to append ..
to sys.path
.
How can I solve this problem? Is there a more efficient way?
The first issue you're getting is due to that from subpackage1 import a
line in your b.py
module.
b.py
is located in your subpackage2
package, a sibling package of subpackage1
. So trying to run from subpackage1 import a
means the subpackage1
is within subpackage2
which is incorrect. Also as side note, in python3 you should never use implicit relative imports as it no longer supports it, so instead use explicit relative imports.
Adding an __init__.py
in each folder turns them in python packages, and you can keep them empty. You want to replace the from subpackage1 import a
with either an explicit relative import like from ..subpackage1 import a
or an absolute import like from Project.subpackage1 import a
. This will be the efficient and correct way to write your package, and you can test it by writing a script that imports Project
and uses its subpackages and modules.
However, I am assuming you are running b.py
as a main module to test the imports. This means you are running command lines that look like: python b.py
. Running it like this gives you a module search path that does not have any of the parent paths like Project
. This would lead to you keep getting ModuleNotFoundErrors even though there's nothing technically wrong with your package. This is why you need a sys.path.append(...
work-around that manually appends your parent path to the module search path in order to run your b.py
module as a main module. If this helps you to test your code then by all means use it, but it is fine to use the absolute and explicit relative imports because modules in a package are supposed to work that way.