在Python中,名称空间包允许您将Python代码分散到多个项目中。当您想要将相关的库作为单独的下载发布时,这很有用。例如,对于PYTHONPATH中的目录Package-1和Package-2,
Package-1/namespace/__init__.py
Package-1/namespace/module1/__init__.py
Package-2/namespace/__init__.py
Package-2/namespace/module2/__init__.py最终用户可以import namespace.module1和import namespace.module2。
定义名称空间包的最佳方式是什么,以便多个Python产品可以在该名称空间中定义模块?
发布于 2014-12-21 10:44:44
TL;DR:
在Python3.3上,你不需要做任何事情,只要不把任何__init__.py放在你的命名空间包目录中,它就会工作。在3.3之前的版本中,选择pkgutil.extend_path()解决方案而不是pkg_resources.declare_namespace()解决方案,因为它是面向未来的,并且已经与隐式名称空间包兼容。
Python3.3引入了隐式名称空间包,请参阅PEP 420。
这意味着现在有三种类型的对象可以由import foo创建
foo.py file__init__.py filefoo表示,由一个或多个目录<代码>D14表示,但不包含任何<代码>D15文件<代码>H216<代码>F217包也是模块,但这里我说的“模块”指的是“非包模块”。
首先,它扫描sys.path中的模块或常规包。如果成功,它将停止搜索,并创建和初始化模块或包。如果它没有找到模块或常规包,但至少找到了一个目录,它就会创建并初始化一个命名空间包。
模块和常规包将__file__设置为创建它们时所用的.py文件。常规和命名空间包都将__path__设置为创建它们的一个或多个目录。
当您执行import foo.bar时,上述搜索将首先搜索foo,然后如果找到包,则使用foo.__path__而不是sys.path作为搜索路径来搜索bar。如果找到foo.bar,则创建并初始化foo和foo.bar。
那么,常规包和名称空间包是如何混合的呢?通常不需要,但是旧的pkgutil显式名称空间包方法已经扩展到包括隐式名称空间包。
如果您有一个现有的常规包,它的__init__.py如下:
from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)..。传统行为是将搜索路径上的任何其他常规包添加到其__path__中。但在Python3.3中,它还添加了名称空间包。
因此,您可以使用以下目录结构:
├── path1
│ └── package
│ ├── __init__.py
│ └── foo.py
├── path2
│ └── package
│ └── bar.py
└── path3
└── package
├── __init__.py
└── baz.py..。只要这两个__init__.py有extend_path行(并且path1、path2和path3在您的sys.path中),import package.foo、import package.bar和import package.baz都可以工作。
pkg_resources.declare_namespace(__name__)尚未更新为包含隐式命名空间包。
发布于 2009-11-05 03:32:17
有一个名为pkgutil的标准模块,您可以使用它将模块‘附加’到给定的命名空间。
使用您提供的目录结构:
Package-1/namespace/__init__.py
Package-1/namespace/module1/__init__.py
Package-2/namespace/__init__.py
Package-2/namespace/module2/__init__.py您应该将这两行放在Package-1/namespace/__init__.py和Package-2/namespace/__init__.py (*)中:
from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)(*由于-unless声明了它们之间的依赖关系-您不知道它们中的哪一个将首先被识别-有关更多信息,请参阅PEP 420 )
正如documentation所说:
这会将以软件包命名的
sys.path目录的所有子目录添加到软件包的__path__中。
从现在开始,您应该能够独立分发这两个包。
发布于 2009-11-05 03:33:52
This section should be pretty self-explanatory.
简而言之,将名称空间代码放在__init__.py中,更新setup.py以声明名称空间,您就可以自由使用了。
https://stackoverflow.com/questions/1675734
复制相似问题