【发布时间】: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