构建Python库是否必须使用完全限定的导入语句?
后续补充的背景信息
我提出这个问题时Python经验尚浅,现在给出几点建议:
- 不要将库代码放在
src目录下 - 不要将可执行Python代码放在单独的
bin目录下 - 不要包含
pyproject.toml
遵循上述要点,对比原问题中的项目结构,你会得到如下结构:
my_project/ main.py liburl/ __init__.py ... .venv
采用该结构后,所有功能都能正常运行:
- 在
my_project目录下运行main.py - 解释器启动时,
main.py的当前工作目录会被添加到解释器搜索路径 - 这意味着解释器无需额外配置即可找到
liburl库
这才是Python的预期使用方式,它不像其他语言那样倾向于分离库源码和使用库的可执行代码。
Python项目结构
我的Python项目结构如下:
- 据我所知,该结构是标准的项目结构。
- 也可能我的认知有误。
- 该结构可能和我的问题有关——在库内部必须使用完全限定名称。
- 如果该设计存在问题,请告知我。
my_project/ bin/ main.py src/ liburl/ __init__.py url_builder.py url_parameter_types/ __init__.py parameter_base.py parameter_boolean.py pyproject.toml .venv
pyproject.toml
[build-system] requires = ["setuptools"] build-backend = "setuptools.build_meta" [project] name = "my_project" version = "1.0.0" description = "My Project" [tools.setuptools.packages.find] where = ["src"]
- 我正在构建一个供
main.py调用的Python库,库名为liburl。 - 在库代码内部,我似乎必须使用完全限定导入语句。
- 这是预期情况吗?无法使用相对导入让我感到奇怪。
示例如下:
url_parameter.py
""" `url_parameter_types` 是和当前文件同一目录下的子目录 """ from url_parameter_types import UrlParameterTristate # 此导入无效 ### ... 剩余代码
另一个示例:
parameter_boolean.py
""" `parameter_base.py` 是和当前文件同一目录下的文件 """ from paramter_base import UrlParameterBase # 此导入无效 ### ... 剩余代码
要让上述示例中的导入语句生效,我必须使用完全限定导入,即:
from liburl.url_parameter_types.parameter_boolean import UrlParameterBoolean
这让我觉得奇怪,原因有三:
- 需要大量额外输入
- 被导入的内容与导入代码在同一目录,我认为它应该对同目录的其他源文件可见
- 如果目录结构变更(构建库时很常见),所有绝对导入语句都需要修改(例如子文件夹重命名或移动,其问题无需额外解释)
最后一个示例:
__init__.py
from url_builder import UrlBuilder
- 我无法从库的根目录导入
url_builder.py中的内容。 - 必须改为:
from liburl.url_builder import UrlBuilder
这就是Python的工作方式吗?无法使用相对导入让我感到意外。
内容的提问来源于stack exchange,提问作者user2138149
相关产品推荐
相关产品推荐

