【问题标题】:Importing module from package raises ModuleNotFoundError for subpackages从包中导入模块会引发子包的 ModuleNotFoundError
【发布时间】:2023-01-09 01:22:13
【问题描述】:

我正在尝试创建一个包(包括几个子包)以供重用和分发。计划是提供一个 CLI 入口点以允许轻松启动。在构建包并将其安装在 virtualenv 中之后,我得到一个 ModuleNotFoundError 用于从主包中包含的子包导入。

我认为这与在 __init__.py 中设置正确的路径有关,但在网上阅读了多个示例后,我仍然很困惑为什么要在 __init__py 中添加任何内容以及那是什么东西。

包的构建使得包名(以及在site-packages 中创建的文件夹)与下面目录结构中的根目录相同。

目录结构是(简化并更改名称):

mypackage
|- __init__.py
|- entrypoint.py
|- subpackage1
|-- __init__.py
|-- module1.py
|- subpackage2
|-- __init__.py
|-- module2.py

笔记所有__init__.py 都是空的

entrypoint.py 是:

from subpackage1.module1 import foo
from subpackage2.module2 import baz

if __name__ == "__main__":
    pass

在我的pyproject.toml 中,我定义:

\[project.scripts\]
mypackage-cli = "maypackage:entrypoint"

使用 pip 安装后,我运行(在我 pip installed 包的 virtualenv 中):

(myvenv) me@mymachine ~ % mypackage-cli

但我得到: ModuleNotFoundError: No module named subpackage1

需要注意两点:

  • 在本地运行源代码时,我没有遇到任何问题
  • 如果我将site-packages 中的文件编辑为具有from mypackage.subpackage1.module1 import foo,则在运行已安装的包时我不会再收到错误,但是当尝试在本地运行相同的修改后的导入(即更改为import mypackage.subpackage1.module1)时在我的开发环境中,我得到一个ModuleNotFoundError

在我的开发环境中打包和本地运行时,让导入工作的正确方法是什么?

谢谢!

【问题讨论】:

  • 您的“顶级可导入包”似乎是mypackage,所以您所有的导入语句都应该从那里开始。例如from mypackage.subpackage1.module1 import foo。 -- 为避免混淆“本地”和“已安装”(在site-packages 中),您应该为项目的目录结构使用所谓的“src-layout”,并结合“可编辑”安装。
  • 你是对的,@sinoroc:为了解决这个问题,我再次查看了目录结构和使用pip install -e。我遵循那里的约定,将导入更改为从项目根目录开始,现在一切正常。

标签: python-import python-packaging


【解决方案1】:

您的“顶级可导入包”似乎是mypackage,所以您所有的导入语句都应该从那里开始。例如from mypackage.subpackage1.module1 import foo

为了避免混淆“local”和“installed”(site-packages),我建议您使用所谓的“src-layout”作为这个项目的目录结构。结合“可编辑”安装,使用起来非常方便。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-02-25
    • 2019-07-03
    • 1970-01-01
    • 2021-07-12
    • 2018-01-31
    • 2021-09-15
    • 1970-01-01
    • 2016-07-30
    相关资源
    最近更新 更多