首页 > 解决方案 > 是否应该避免在自己的命名空间中命名 Python 模块?

问题描述

我一直在学习创建 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>).

我在想:

  1. 在自己的命名空间中包含或不包含包是否有有意的、既定的理由,如果是,那理由是什么?
  2. 大名鼎鼎的 Python 包在其目录结构或分发/打包文件(pyproject.tomlsetup.cfgsetup.py等)的底层做了什么,以避免将包包含在自己的命名空间中?

感谢您通知一位好奇的新手包作者。

标签: pythonimportpackagedirectory-structure

解决方案


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

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

请注意,from tqdm import tqdm实际上是从模块导入对象 ,因此它实际上并不是顶部的空导入层 - 模块包含一堆其他对象。tqdm tqdm

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

推荐阅读