'__import __('pkg_resources')。declare_namespace(__ name __)`是做什么的?

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

 __import__('pkg_resources').declare_namespace(__name__) 

它做了什么,为什么人们使用它? 假设它在运行时与dynamic导入和创build名称空间有关。

它归结为两件事情:

  1. __import__是一个Python函数,它将使用一个string作为包的名称来导入一个包。 它返回一个代表导入包的新对象。 因此, foo = __import__('bar')将导入一个名为bar的包,并将对其对象的引用存储在本地对象variablesfoo

  2. 从安装程序使用pkg_resources的文档declare_namespace()声明虚包名称是一个“名称空间包”,其包含的包和模块可能分布在多个发行版中。

所以__import__('pkg_resources').declare_namespace(__name__)会将'pkg_resources'包导入到一个临时对象中,并调用存储在临时对象中的__import__函数(可能使用了__import__函数而不是import语句,这样就没有额外的符号留在名为pkg_resources )。 如果此代码位于my_namespace/__init__.py ,则__name__my_namespace并且此模块将包含在my_namespace名称空间包中。

有关更多详细信息,请参阅设置工具文档

看到这个问题讨论旧机制达到相同的效果。

从PEP420开始,提供了类似function的标准化机制。

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

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

想象一下,你分发一个具有很多function的软件产品,并不是所有的人都想要它,所以你把它分成几块,然后作为可选的插件发货。

你希望人们能够做到

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

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

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

但是,如果你把这两个插件作为单独的python包运行,那么它们位于两个不同的目录中呢? 那么你可能需要在每个包的__init__.py放入__import__('pkg_resources').declare_namespace(__name__) ,这样Python就知道这些包是更大的“名称空间包”的一部分,在我们的例子中是your_project.plugins

有关更多信息,请参阅文档 。

内森,这个描述看起来不正确:“所以__import__('pkg_resources').declare_namespace(__name__)将从pkg_resources包中导入所有符号,然后将它们添加到名称存储在__name__的名称空间。

declare_namespace不会将pkg_resources包中的符号添加到名称存储在__name__的名称空间。

declare_namespace执行以下操作:“声明该包”packageName“是一个名称空间包”。 参考: http : //galaxy.readthedocs.io/en/master/lib/pkg_resources.html#pkg_resources.declare_namespace