`__import__('pkg_resources').declare_namespace(__name__)` 有啥作用?

Posted

技术标签:

【中文标题】`__import__(\'pkg_resources\').declare_namespace(__name__)` 有啥作用?【英文标题】:What does `__import__('pkg_resources').declare_namespace(__name__)` do?`__import__('pkg_resources').declare_namespace(__name__)` 有什么作用? 【发布时间】:2011-12-08 19:32:02 【问题描述】:

在一些 __init__.py 模块文件中,我看到了这样一行:

__import__('pkg_resources').declare_namespace(__name__)

它有什么作用以及人们为什么使用它?假设它与在运行时动态导入和创建命名空间有关。

【问题讨论】:

您可能会发现这个问题和答案很有帮助:***.com/questions/5064951/… 【参考方案1】:

归结为两件事:

    __import__ 是一个 Python 函数,它将使用字符串作为包的名称来导入包。它返回一个表示导入包的新对象。所以foo = __import__('bar') 将导入一个名为bar 的包并将对其对象的引用存储在本地对象变量foo 中。

    来自 setup utils pkg_resources' 文档,declare_namespace() “声明 [s] 点分包名称 name 是一个“命名空间包”,其包含的包和模块可能分布在多个分布。”

所以__import__('pkg_resources').declare_namespace(__name__) 将'pkg_resources' 包导入一个临时文件并调用存储在该临时文件中的declare_namespace 函数(可能使用__import__ 函数而不是import 语句,因此没有额外的剩下的符号名为pkg_resources)。如果这段代码在my_namespace/__init__.py 中,那么__name__ 就是my_namespace,并且这个模块将包含在my_namespace 命名空间包中。

有关更多详细信息,请参阅setup tools 文档

请参阅this question,了解有关实现相同效果的旧机制的讨论。

有关从 Python 3.3 开始提供类似功能的标准化机制,请参阅 PEP 420。

【讨论】:

import 是 Python 函数,而不是语句。 @PierreThibault 已修复。谢谢! 什么?不!这根本不是declare_namespace 所做的。它不只是将pkg_resources 模块的内容转储到选定的命名空间中; pkg_resources 只是 declare_namespace 来自的模块。包foo 将使用pkg_resources.declare_namespace(__name__) 以允许将其实现拆分为多个foo 文件夹。将pkg_resources 本身的内容拉入您的命名空间将完全适得其反。 @user2357112 不确定我在大约 5 年前得到了什么。我相应地更新了响应。【参考方案2】:

这是在 Python 中声明所谓的“命名空间包”的一种方式。

这些是什么,有什么问题:

假设您分发的软件产品具有很多功能,但并非所有人都想要它,因此您将其拆分为多个部分并作为可选插件发布。

你希望人们能够做到

import your_project.plugins.plugin1
import your_project.plugins.plugin2
...

如果你的目录结构和上面的完全一样就好了,即

your_project/
    __init__.py
    plugins/
        __init__.py
        plugin1.py
        plugin2.py

但是,如果您将这两个插件作为单独的 python 包发布,以便它们位于两个不同的目录中呢? 那么您可能希望将__import__('pkg_resources').declare_namespace(__name__) 放在每个包的__init__.py 中,以便Python 知道这些包是更大的“命名空间包”的一部分,在我们的例子中是your_project.plugins

更多信息请参考documentation。

【讨论】:

以上是关于`__import__('pkg_resources').declare_namespace(__name__)` 有啥作用?的主要内容,如果未能解决你的问题,请参考以下文章

pkg_resources.DistributionNotFound: The 'pip==7.1.0' distribution was not found and is requi

import和 __import__

Python:import 与__import__()

动态导入模块:__import__importlib动态导入的使用场景

Python函数 __import__()

python __import__