3

I am working on a Python project with the basic folder structure listed below, and examples of what each Python file contains is in curly brackets.

|   generate_recommendations.py
├───.ipynb_checkpoints
├───.vscode
├───csv
├───dao
|   |   ratingDAO.py { contains a class named RatingDAO }
│   ├───config
│   ├───core
|   |       rating.py { contains a class named Rating }
│   ├───db

OBJECTIVE: I want to import rating.py in ratingDAO.py, and in turn want to import ratingDAO.py into generate_recommendations.py, and have all imports working.

I have added the following import statement in the file ratingDAO.py

from core.rating import Rating

And I have also added the following import statement in the file generate_recommendations.py

from dao.ratingDAO import RatingDAO

When I execute ratingDAO.py, it runs without any error.

But when I try to execute generate_recommendations.py, I get the following error

Traceback (most recent call last):
  File "generate_recommendations.py", line 3, in <module>
    from dao.ratingDAO import RatingDAO
  File "D:\MEGASync\BSc Computer\Research Papers\recommendation-engine\dao\ratingDAO.py", line 3, in <module>
    from core.rating import Rating
ModuleNotFoundError: No module named 'core'

I am unable to resolve the error. I have seen approx ten posts on StackOverflow related to nested imports but I was unable to find examples where the author tried to import two levels deep.

If such imports are not possible in Python, I am open to ideas on how I should go about managing the files in my Python project.

In Java, I would've used the following folder structure,

├───recommendation
|   |   GenerateRecommendations.java
│   ├───core
|   |     Rating.java
│   └───dao
|         RatingDAO.java 

and used the following code to import Rating.java in RatingDAO.java,

import recommendation.core.Rating;

and used the following to code to import RatingDAO.java into GenerateRecommendations.java

import dao.RatingDAO;

and everything would have worked, but the same wasn't working for Python which is why I chose the initial specified folder structure.

P.S This is my first time asking a question on StackOverflow. I tried my best to describe my issue by referring to other posts. Apologies in advance if it does not match the standards of good questions.

Hoping for a reply! :-)

1
  • don't take this badly, but Python does not have the 1 class per file Java limitation. Don't write Java in Python. dirtsimple.org/2004/12/python-is-not-java.html I realize that this does not answer your question, but your module structure seems unnecessarily complex to me. ratingDAO.py { contains a class named RatingDAO } => I was already thinking hah! a Java programmer before you mentioned the language. Commented Mar 24, 2020 at 21:45

1 Answer 1

5

When you run python generate_recommendations.py this puts the script's directory on the path (sys.path which is searched for modules when importing). When you use from core.rating import Rating in ratingDAO.py then it will search the path for a package called core but since the dao directory is not on the path it cannot be found.

A solution is to use a relative import in the ratingDAO.py module:

from .core.rating import Rating

This way it will search relative to its own location for the core package. If you want to run ratingDAO.py from the top-level directory you can do so via python -m dao.ratingDAO (this put's the current working directory on the path and then searches sys.path for a module called dao.ratingDAO and executes it).

Or you can use an absolute import relative to the top-level directory of the hierarchy:

from dao.core.rating import Rating
Sign up to request clarification or add additional context in comments.

4 Comments

Following your suggestion, I used the following import statement in ratingDAO.py module, from .core.rating import Rating. Now, if I run generate_recommendations.py I do not get any ModuleNotFoundError. Thank you. But, if I now try to run ratingDAO.py seperately using python ratingDAO.py, it gives me the following error. from .core.rating import Rating ModuleNotFoundError: No module named '__main__.core'; '__main__' is not a package. In a similar manner, if I use from dao.core.rating import Rating in ratingDAO.py and run generate_recommendations.py I get no error.
But, upon executing ratingDAO.py as stated above, I get from dao.core.rating import Rating ModuleNotFoundError: No module named 'dao'
@RanajoySaha You need to run python -m dao.ratingDAO from outside the dao directory.
Thank you very much. Now the code works. Thank you! Much appreciated!

Your Answer

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.