是否应该避免在自己的命名空间中命名 Python 模块?

Should one avoid a Python module being named in its own namespace?

我一直在学习如何创建 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 软件包 do 在他们的命名空间中列出了自己,但大多数大牌 Python 包 在它们自己的命名空间中列出它们自己。

我发现我正在创建的包确实在它自己的命名空间中列出了自己,这使得上述观察与我相关。

考虑一个可能会产生实际后果的用例:一个模块在其自己的命名空间中列出,并且递归搜索 dir(<module>) 中的子模块名称的过程开始。模块名称 module 将在无限循环中作为子模块返回,因为 module 始终在 dir(<module>).

我在想:

  1. 在其自己的命名空间中包含或不包含包是否有一个有意的、既定的理由,如果有,理由是什么?
  2. 大牌 Python 软件包在其目录结构或 distribution/packaging 文件中做了什么(pyproject.tomlsetup.cfgsetup.py等)以避免将包包含在它自己的命名空间中?

感谢您告知一位好奇的包编写新手。

评论太长; TLDR:尽量避免额外导入并显示代码以获得具体建议。

  1. 不,对此没有既定的理由。做任何有意义的事情。更短的导入对用户更友好;必须在顶部引入无操作导入层的情况非常罕见。

注意 from tqdm import tqdm 实际上是从 module tqdm 导入 object tqdm,所以它顶部并不是真正的空导入层 - 该模块包含一堆其他对象。

  1. Python项目多种多样。事实上,许多知名项目都是用其他语言编写的,例如 C/C++。它们都有不同的文件夹结构,因此没有一种适合所有人。