'__import __('pkg_resources')。declare_namespace(__ name __)`是做什么的?
在一些模块的__init__.py
文件中,我看到了这样一行:
__import__('pkg_resources').declare_namespace(__name__)
它做了什么,为什么人们使用它? 假设它在运行时与dynamic导入和创build名称空间有关。
它归结为两件事情:
-
__import__
是一个Python函数,它将使用一个string作为包的名称来导入一个包。 它返回一个代表导入包的新对象。 因此,foo = __import__('bar')
将导入一个名为bar
的包,并将对其对象的引用存储在本地对象variablesfoo
。 -
从安装程序使用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