命名空间包 __spec__.loader 和 __loader__ 属性未设置为 None

Namespace package __spec__.loader and __loader__ attributes not set to None

Python Language Reference 状态:

To indicate to the import machinery that the spec represents a namespace portion. the path entry finder sets “loader” on the spec to None and “submodule_search_locations” to a list containing the portion.

Python Library Reference 状态:

The loader to use for loading. For namespace packages this should be set to None.

但正在创建一个名称空间包,其部分位于文件系统上的两个不同路径 a/b/ 中:

a/
  namespace_package/
    module_1.py
    module_2.py
b/
  namespace_package/
    module_3.py

然后将这些路径添加到 PYTHONPATH 环境变量:

export PYTHONPATH="a:b"

最后导入命名空间包并使用 CPython 3.7 解释器打印其 __spec__.loader__loader__ 属性:

python3 -c "import namespace_package; print(namespace_package.__spec__.loader); print(namespace_package.__loader__)"

表明它们是 不是 None:

<_frozen_importlib_external._NamespaceLoader object at 0x104b04128> <_frozen_importlib_external._NamespaceLoader object at 0x104b04128>

这是文档错误、实现错误还是我的误解?

我猜它曾经是 None,但由于 Python 的变化而不再存在。它给你带来了麻烦吗?如果是这样,那么我会提出一个问题,但解决方案很可能是更新文档。你能检查一下 Python 3.6 and/or 3.5 得到的结果吗?也可能值得检查 Python 发行说明以查看此区域中有哪些更新。

在这种情况下,mod.__spec__.loadermod.__loader__ 不同。规范的加载器应该仍然是 None。模块的加载程序由导入机制设置为内部 _NamespaceLoader 的一个实例,部分原因是为了重新加载。也许文档对此不够清楚。

看起来像 it was right but has been changed

打开一个问题来跟踪它:https://bugs.python.org/issue35181