T81
T81

Reputation: 171

ModuleNotFound: No module named 'module_name'

My project structure is the following:

.
└── project name
     ├── project name
     │   ├── __init__.py
     │   ├── module.py
     │  
     ├── PACKAGE_A
     │   ├── __init__.py
     │   ├── PACKAGE_A.py
     │   ├── module_a.py
     │

In PACKAGE_A.py

from module_a import Some_Class

a = Some_Class()

class Another_Class:
    # class code here

In module.py

"""
Notes
-----
https://stackoverflow.com/questions/16780014/import-file-from-parent-directory
"""

# Standard library imports
import os, sys
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

# Local application imports
from PACKAGE_A.PACKAGE_A import Another_Class
from PACKAGE_A.module_a import some_function

While module_a.py and PACKAGE_A.py run without problem, running module.py fails with:

Traceback (most recent call last):
  File "path\to\project name\project name\module.py", line 12, in <module>
    from PACKAGE_A.PACKAGE_A import Another_Class
  File "path\to\project name\PACKAGE_A\PACKAGE_A.py", line 1, in <module>
    from module_a import Some_Class
ModuleNotFoundError: No module named 'module_a'

What am I doing wrong here?

Upvotes: 0

Views: 4011

Answers (2)

Ghassen Manai
Ghassen Manai

Reputation: 81

You need to change your import statement in PACKAGE_A.py from:

from module_a import Some_Class

to:

from PACKAGE_A.module_a import Some_Class

The reason is that you are adding the path\to\project name\ to sys.path, but you have no module_a.py in path\to\project name\, and path\to\project name\PACKAGE_A (where module_a.py resides) is not in sys.path.

As for why you succeed in running everything in PACKAGE_A, it's because Python adds the directory containing the script you are running to the list (as explained by gaFF).

I would recommend you read a bit more about python imports, if the doc seems too cluttered, you can check this link.

This is a personal preference, but I find it simpler to add the root directory of the project to the PYTHONPATH environment variable and then running all the scripts from that directory's level and changing the import statements accordingly. In your example, the root directory would be path\to\project name\.

Upvotes: 1

gaFF
gaFF

Reputation: 757

import search for your packages in specific places, listed in sys.path. See the doc for the full details.

The current directory is always appended to this list, that's why you succeed to run everything inside PACKAGE_A. But from project name, there is no way to know where to find PACKAGE_A.

Solutions include:

  • use relative import
  • always run from the root directory (and start all your imports from the root directory)
  • add the root directory to the environment variable PYTHONPATH (same)
  • use a tool which sets PYTHONPATH when you enter your virtual environment (same)
  • ...

and depends on your project and your needs.

Upvotes: 1

Related Questions