3

Let us suppose we have the following structure:

outer_module.py|
               |subfolder|
                         |__init__.py
                         |inner_module.py
                         |foo.py

In outer_module.py we'd have:

from subfolder.inner_module import X

In inner_module.py we'd have:

from foo import Y

Then I get a ModuleNotFoundError: No module named 'foo' running the outer_module.py. How can I import this submodule that imports a submodule without getting a ModuleNotFoundError?

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Ericson Willians
  • 7,606
  • 11
  • 63
  • 114

2 Answers2

5

from foo imports from a top level module foo. You need to explicitly qualify that you are looking for a module in the same package.

Use .foo to indicate you are importing from the same package:

from .foo import Y

You can also specify an absolute path, but then you have to include the package name:

from subfolder.foo import Y

Quoting from the import statement documentation:

When specifying what module to import you do not have to specify the absolute name of the module. When a module or package is contained within another package it is possible to make a relative import within the same top package without having to mention the package name. By using leading dots in the specified module or package after from you can specify how high to traverse up the current package hierarchy without specifying exact names. One leading dot means the current package where the module making the import exists. Two dots means up one package level. Three dots is up two levels, etc. So if you execute from . import mod from a module in the pkg package then you will end up importing pkg.mod. If you execute from ..subpkg2 import mod from within pkg.subpkg1 you will import pkg.subpkg2.mod.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • But this way you can call `from subfolder.inner_module import X` from only in outer_module or a script from same directory. If you call it from another main script from lets say `subfolder/inner_main.py` you'll get error: `ImportError: attempted relative import with no known parent package` – vslzl Jan 26 '22 at 12:28
  • @vslzl: [don't put scripts inside your packages](https://stackoverflow.com/a/69102148/100297). Use a `__main__` module in your package and `python -m yourpackage`, or install your script as a console entry. – Martijn Pieters Jan 26 '22 at 13:33
1

In inner_module.py, either use a relative or absolute import:

from .foo import Y

# or

from subfolder.foo import Y

Documentation links:

codeape
  • 97,830
  • 24
  • 159
  • 188