【发布时间】:2021-11-02 04:35:16
【问题描述】:
我一直在学习如何创建 Python 包和 Python 导入系统,因为我是第一次尝试制作自己的 Python 包,并尽可能遵循“最佳实践”。
在此过程中,我注意到一些著名的 Python 包在其命名空间中命名,而有些则没有。我在 Python 3.8.10 中测试的一个小样本,带有包版本:
>>> import numpy, matplotlib, scipy, tqdm, setuptools
>>> "numpy" in dir(numpy), "matplotlib" in dir(matplotlib), "scipy" in dir(scipy), "tqdm" in dir(tqdm), "setuptools" in dir(setuptools)
(False, False, False, True, True)
>>> numpy.__version__, matplotlib.__version__, scipy.__version__, tqdm.__version__, setuptools.__version__
('1.20.2', '3.4.2', '1.6.3', '4.60.0', '49.6.0.post20210108')
从这个示例和其他示例中,似乎至少有一些大牌 Python 包确实在它们的命名空间中列出了自己,但大多数大牌 Python 包没有 在自己的命名空间中列出自己。
我发现我正在创建的包确实在它自己的命名空间中列出了自己,这使得上述观察与我相关。
考虑一个可能产生实际后果的用例:一个模块列在它自己的命名空间中,并且开始一个在dir(<module>) 中递归搜索子模块名称的过程。模块名称module 将在无限循环中作为子模块返回,因为module 始终在dir(<module>) 中。
我想知道:
- 在自己的命名空间中包含或不包含包是否存在有意的、既定的理由,如果是,那么理由是什么?
- 大名鼎鼎的 Python 包在其目录结构或分发/打包文件(
pyproject.toml、setup.cfg、setup.py等)的底层做了什么以避免将包包含在自己的命名空间中?
感谢您通知一位好奇的新手包编写者。
【问题讨论】:
-
dir并没有准确地给你一个对象的命名空间,顺便说一句。 -
顺便说一句,
setuptools本身的原因是因为setuptools.__init__导入了setuptools.version
标签: python import package directory-structure