joe*_*ker 132 python namespaces package
在Python中,命名空间包允许您在多个项目中传播Python代码.当您想要将相关库作为单独的下载发布时,这非常有用.例如,使用目录Package-1和Package-2in PYTHONPATH,
Package-1/namespace/__init__.py
Package-1/namespace/module1/__init__.py
Package-2/namespace/__init__.py
Package-2/namespace/module2/__init__.py
Run Code Online (Sandbox Code Playgroud)
最终用户可以import namespace.module1和import namespace.module2.
定义命名空间包的最佳方法是什么,因此多个Python产品可以在该命名空间中定义模块?
Mik*_*cki 79
有一个名为pkgutil的标准模块,您可以使用该模块将模块"附加"到给定的命名空间.
使用您提供的目录结构:
Package-1/namespace/__init__.py
Package-1/namespace/module1/__init__.py
Package-2/namespace/__init__.py
Package-2/namespace/module2/__init__.py
Run Code Online (Sandbox Code Playgroud)
你应该把这两行放在两个Package-1/namespace/__init__.py和Package-2/namespace/__init__.py(*)中:
from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)
Run Code Online (Sandbox Code Playgroud)
(*因为 - 你没有说明他们之间的依赖关系 - 你不知道他们中的哪一个将被首先识别 - 有关更多信息,请参阅PEP 420)
正如文件所说:
这将添加到软件包的
__path__所有目录子目录中sys.path.
从现在开始,您应该能够独立分发这两个包.
cla*_*cke 69
TL; DR:
在Python 3.3上,你不必做任何事情,只是不要__init__.py在你的命名空间包目录中放任何东西,它就会起作用.在3.3之前的版本中,选择一个pkgutil.extend_path()解决方案pkg_resources.declare_namespace(),因为它具有面向未来并且已经与隐式命名空间包兼容.
Python 3.3引入了隐式命名空间包,请参阅PEP 420.
这意味着现在可以通过以下方式创建三种类型的对象import foo:
foo.py文件表示的模块foo包含__init__.py文件的目录表示foo没有任何__init__.py文件包也是模块,但在这里我的意思是"非包装模块"当我说"模块".
首先,它扫描sys.path模块或常规包.如果成功,它将停止搜索并创建和初始化模块或包.如果它没有找到模块或常规包,但它找到了至少一个目录,则会创建并初始化命名空间包.
模块和常规包已__file__设置为.py从中创建的文件.常规和命名空间包已__path__设置为创建它们的目录.
当你这样做import foo.bar,上面的搜索首先发生的foo,如果一个包被发现,那么,寻找bar与完成foo.__path__的搜索路径,而不是sys.path.如果foo.bar被发现,foo并foo.bar创建和初始化.
那么常规包和命名空间包如何混合?通常它们不会,但旧的pkgutil显式命名空间包方法已扩展为包含隐式命名空间包.
如果您有一个__init__.py类似于此的现有常规包:
from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)
Run Code Online (Sandbox Code Playgroud)
...遗留行为是将搜索到的路径上的任何其他常规包添加到其中__path__.但是在Python 3.3中,它还添加了命名空间包.
所以你可以有以下目录结构:
??? path1
? ??? package
? ??? __init__.py
? ??? foo.py
??? path2
? ??? package
? ??? bar.py
??? path3
??? package
??? __init__.py
??? baz.py
Run Code Online (Sandbox Code Playgroud)
......只要两个__init__.py人extend_path有线(和path1,path2并且path3在你的身上sys.path)import package.foo,import package.bar并且import package.baz都会有效.
pkg_resources.declare_namespace(__name__) 尚未更新为包含隐式命名空间包.
简而言之,将命名空间代码放入__init__.py,更新setup.py以声明命名空间,您可以自由选择.
| 归档时间: |
|
| 查看次数: |
50540 次 |
| 最近记录: |