`__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