【问题标题】:Should one avoid a Python module being named in its own namespace?是否应该避免在自己的命名空间中命名 Python 模块?
【发布时间】: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>) 中。

我想知道:

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

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

【问题讨论】:

  • dir 并没有准确地给你一个对象的命名空间,顺便说一句。
  • 顺便说一句,setuptools 本身的原因是因为setuptools.__init__ 导入了setuptools.version
  • 感谢您对dir@juanpa.arrivillaga 的看法。我刚刚从this postthis post 以及docs here 中了解了属性和命名空间之间的区别。

标签: python import package directory-structure


【解决方案1】:

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

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

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

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

【讨论】:

  • 感谢您分享这些想法@Marat。我很高兴听到没有一刀切的命名空间标准俱乐部,如果我的包由于结构和导入而将自己置于其命名空间中,它将把我放在它的顽皮名单上。我主要对公认的标准及其背后的基本原理感到好奇,而不一定是修改我的特定包的方法。
  • @DoodleVib 我对你有感觉。分享你的代码,我可以提出关于模块结构的具体建议。
猜你喜欢
  • 2020-01-03
  • 1970-01-01
  • 2020-05-13
  • 1970-01-01
  • 2015-03-05
  • 1970-01-01
  • 1970-01-01
  • 2014-01-26
  • 2013-04-12
相关资源
最近更新 更多