我有一个带有 src 布局的 Python 包
superpackage
,我正在尝试添加另一个也带有 src 布局的包 pack1
作为子模块。两者都是 git 目录。
我的目标是简化导入语句,以便我可以直接从
module1
导入 superpackage.pack1
,而无需指定整个路径。
这是我的
superpackage
的基本结构:
superpackage/
├── .git/
├── src/
│ └── superpackage/
│ ├── __init__.py
│ ├── pack1/ # submodule pointing to pack1 repository
├── setup.cfg
└── pyproject.toml
以及
pack1
的结构:
pack1/
├── .git/
├── src/
│ └── pack1/
│ ├── __init__.py
│ └── module1.py
我使用以下命令将
pack1
作为子模块添加到 superpackage
:
cd superpackage
git submodule add ../pack1 src/superpackage/pack1
git commit -am "Added pack1 as submodules"
目前,要访问
module1
,我需要使用冗长的导入语句:
from superpackage.pack1.src.pack1 import module1
但是,我想做的是:
from superpackage.pack1 import module1
我找到的唯一解决方案是在
__init__.py
中添加一个 src/pack1
文件,其中包含以下行:
from .src.pack1 import module1
但是,这个解决方案似乎不太通用,需要对每个模块进行修改。我还担心对子模块的潜在影响。
如何实现所需的导入行为?还有别的办法吗?
为了解决导入路径问题,我决定使用 @sinoroc 提到的 Python 的命名空间包功能。此功能允许多个目录共同充当单个 Python 包
我修改了 pack1 的 setup.cfg 以将其声明为名称空间包。 setup.cfg 的外观如下:
[metadata]
name = superpackage-pack1
version = 0.1.0
[options]
package_dir =
=src
packages = find_namespace:
[options.packages.find]
where = src
结构变成:
superpackage/
├── .git/
├── src/
│ └── superpackage/
│ ├── __init__.py
│ ├── module.py
├── setup.cfg
└── pyproject.toml
以及pack1的结构:
pack1/
├── .git/
├── src/
│ └── superpackage/
│ └── pack1/
│ ├── __init__.py
│ └── module1.py
它允许将 pack1 作为单个实体进行分发,并且仍然可以保持以前对 pack1 的使用:
from superpackage.pack1 import module1
但不是作为单一实体:
from pack1 import module1
除非我修改setup.cfg
它还有一个缺点,就是强制独立安装像 pack1 这样的所有子包,但我想这没问题