如何为独立包创建显式公共伪命名空间,避免冲突且不嵌套目录?
实现显式公共伪命名空间包(无需冗余嵌套目录)
要实现foo.bar公共命名空间下的独立包(如foo.bar.package1、foo.bar.package2),且每个包单独存放在独立仓库、无需嵌套三级目录,可通过Python的显式命名空间包机制实现,具体步骤如下:
单个独立包的项目结构
以package1为例,仓库结构只需保持必要的命名空间层级(无需额外冗余嵌套):
foo/ bar/ __init__.py package1/ __init__.py pyproject.toml
配置命名空间的显式声明
在foo/__init__.py和foo/bar/__init__.py中添加命名空间扩展代码,让Python识别这是可合并的公共命名空间:
# foo/__init__.py __path__ = __import__('pkgutil').extend_path(__path__, __name__)
# foo/bar/__init__.py __path__ = __import__('pkgutil').extend_path(__path__, __name__)
子包的代码编写
在foo/bar/package1/__init__.py中编写该包的业务代码,例如:
# foo/bar/package1/__init__.py def run(): print("执行 package1 的功能")
打包配置(pyproject.toml)
使用setuptools配置打包信息,确保包被正确识别为foo.bar命名空间下的子包:
[build-system] requires = ["setuptools>=61.0"] build-backend = "setuptools.build_meta" [project] name = "foo-bar-package1" # 唯一包名,避免PyPI冲突 version = "0.1.0" packages = ["foo.bar.package1"]
其他独立包的复用方式
package2的仓库结构、命名空间配置、打包逻辑完全复用package1的模式,只需将package1替换为package2,并修改pyproject.toml中的包名和版本即可。
使用效果
当foo-bar-package1和foo-bar-package2都安装后,在任意Python项目中可以这样调用:
from foo import bar # 直接通过公共命名空间访问各个独立包 bar.package1.run() bar.package2.run() # 假设package2也定义了run方法
这种方式既实现了公共命名空间的隔离(避免命名冲突),又让每个包保持独立仓库、可单独安装,同时无需维护冗余的深层嵌套目录。
内容的提问来源于stack exchange,提问作者matt.baker
相关产品推荐
相关产品推荐

