Python导入嵌套模块时出现“ModuleNotFound”错误

3

我正在开发一个Python项目,基本的文件夹结构如下所示,每个Python文件包含的示例在花括号中。

|   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

目标: 我想在ratingDAO.py中导入rating.py,并且反过来想要在generate_recommendations.py中导入ratingDAO.py,确保所有的导入都正常工作。

我已经在ratingDAO.py文件中添加了以下导入语句。

from core.rating import Rating

我还在generate_recommendations.py文件中添加了以下导入语句。
from dao.ratingDAO import RatingDAO

当我执行ratingDAO.py时,它可以正常运行且没有错误。

但是当我尝试执行generate_recommendations.py时,我会遇到以下错误:

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'

我无法解决这个错误。我在 StackOverflow 上看到了大约十篇涉及嵌套导入的帖子,但是我无法找到作者尝试导入两层嵌套的示例。

如果在Python中不可能进行这样的导入,我愿意听取有关如何管理我的Python项目中的文件的建议。

在Java中,我会使用以下文件夹结构:

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

并在RatingDAO.java中使用以下代码导入Rating.java文件,

import recommendation.core.Rating;

然后使用以下代码将 RatingDAO.java 导入 GenerateRecommendations.java 中:

import dao.RatingDAO;

一切都应该能够正常工作,但对于Python来说同样的方法并没有奏效,因此我选择了最初指定的文件夹结构。
顺便说一下,这是我第一次在StackOverflow上提问。我尽力通过参考其他帖子来描述我的问题。如果它不符合好问题的标准,我先道歉。
期待回复! :-)

不要误解,但Python没有Java每个文件一个类的限制。不要在Python中写Java。https://dirtsimple.org/2004/12/python-is-not-java.html 我知道这并没有回答你的问题,但是你的模块结构对我来说似乎过于复杂。ratingDAO.py {包含名为RatingDAO的类}=>在你提到这种语言之前,我已经在想“哈!一个Java程序员”。 - JL Peyret
1个回答

4
当您运行python generate_recommendations.py时,这将在路径上放置脚本目录(sys.path,在导入时搜索模块)。当您在ratingDAO.py中使用from core.rating import Rating时,它会在路径中搜索名为core的包,但是由于dao目录不在路径上,因此找不到。
解决方案是在ratingDAO.py模块中使用相对导入:
from .core.rating import Rating

这样可以相对于自己的位置搜索core包。如果你想从最高层目录运行ratingDAO.py,可以通过python -m dao.ratingDAO实现(这会将当前工作目录放在路径上,然后在sys.path中搜索名为dao.ratingDAO的模块并执行它)。

或者你可以使用相对于层次结构最高级目录的绝对导入:

from dao.core.rating import Rating

根据您的建议,我在ratingDAO.py模块中使用了以下导入语句:from .core.rating import Rating。现在,如果我运行generate_recommendations.py,就不会出现ModuleNotFoundError错误。谢谢您。但是,如果我现在尝试单独运行ratingDAO.py,并使用python ratingDAO.py命令,就会出现以下错误:from .core.rating import Rating ModuleNotFoundError: No module named '__main__.core'; '__main__' is not a package。类似地,如果我在ratingDAO.py中使用from dao.core.rating import Rating并运行generate_recommendations.py,就不会出现任何错误。 - Ranajoy Saha
但是,按照上述说明执行 ratingDAO.py 后,我收到了 from dao.core.rating import Rating ModuleNotFoundError: No module named 'dao' 的错误提示。 - Ranajoy Saha
@RanajoySaha 你需要从 dao 目录之外运行 python -m dao.ratingDAO - a_guest
非常感谢。现在代码可以运行了。谢谢!非常感激! - Ranajoy Saha

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接