pythoncode-organizationmodulenotfounderror

"ModuleNotFoundError" when importing modules


A similar question was asked at: Python subpackage import "no module named x" But I was still not able to solve my problem.

For the first time, I divided my python code into modules and packages. Here is how the files are set up (not with the real names):

└── projectfolder
    |––main.py
    |––package1
        |--__init.py__
        |--module1.py
        |--subpackage1
            |--__init.py__
            |--module2.py

Inside module2.py there is a function ("function1") that is supposed to be used inside a function ("function2") in module1.py. Function2 is then supposed to be used inside main.py.

This is firstly done by importing suppackage1 inside module1:

import subpackage1

This is the code inside the __init__.py inside subpackage1:

from .module2 import function1

Function1 is then used inside function2 which lies in module1.py like this:

subpackage1.function1()

Which does not create any error message. But now I want to call function2 in main.py. Package1 is imported in main.py like this:

import package1

This is the code inside the __init__.py file inside package1:

from .module1 import function2

I was then expecting that I could use function2 without a problem in main.py like this:

package1.function2()

But when running the code from main.py I get this error message:

Error:

"Inside main.py" import package1
"Inside __init__.py which lies in package1" from .module1 import function2
"Inside module1.py" ModuleNotFoundError: No module named 'subpackage1'

What have I done wrong? And is there a better way to organize packages and modules? Because this is already hard to manage only with a few files.


Solution

  • Briefly:

    When you run main.py your subpackage1 is out of the scope, therefore you can't import it with import subpackage1. More info on this topic here.

    Consider rewriting import subpackage1 like:

    from package1 import subpackage1
    

    Or add it to the PYTHONPATH env variable, but I personally find that way more confusing