命名空间Python包(没有__init__.py)和常规Python包(具有__init__.py)之间有什么区别,特别是当__init__.py对于常规包是空的时候?
我很好奇,因为最近我忘了在我制作的包裹中制作__init__.py,我从来没有注意到任何问题.实际上,它们似乎与常规包装相同.
编辑:仅支持Python 3.3(see PEP 420)的命名空间包,所以很自然地,这个问题仅适用于Python 3.
解决方法:
命名空间包
命名空间包是一种特殊的包,允许您在Python路径的不同点统一两个具有相同名称的包.例如,将path1和path2视为Python路径上的单独条目:
path1
+--namespace
+--module1.py
+--module2.py
path2
+--namespace
+--module3.py
+--module4.py
通过这种安排,您应该能够执行以下操作:
from namespace import module1, module3
因此,您可以在单个命名空间中统一两个具有相同名称的包.如果它们中的任何一个具有成为包的__init__.py – 并且您不再获得统一,因为忽略了另一个目录.
曾经需要__init__.py来使目录成为一个包
命名空间包是没有__init__.py的包.
有关简单包的示例,如果您有一个目录:
root
+--package
+--file1.py
+--file2.py
...
虽然您可以在包目录中独立运行这些文件,例如使用python file1.py或python3 file1.py,您将无法将文件作为模块导入根目录,例如
import module.file1
会失败,为了让它起作用,你至少需要这个:
module
+--__init__.py
+--file1.py
+--file2.py
...
__init__.py初始化包,并且您可以在首次导入模块时运行的__init__.py中包含代码,
run_initial_import_setup()
提供__all__要导入的名称列表,
__all__ = ['star_import', 'only', 'these', 'names']
如果使用以下内容导入:
from module import *
或者,如果您只想导入目录中剩余的.py文件,则可以将其保留为空,但这是要求能够执行此操作.
命名空间:
您最初可以使用pkgutil,自Python 2.3起可用.通过在每个单独的包的__init__.py中添加以下内容来完成添加命名空间:
from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)
Setuptools使用类似的方法,同样,所有__init__.py文件应包含以下内容(没有其他代码):
import pkg_resources
pkg_resources.declare_namespace(__name__)
命名空间在PEP 420中得到了更彻底的解决
另请参阅此处有关setuptools和命名空间的更多讨论:
标签:python,python-3-x,package
来源: https://codeday.me/bug/20190930/1836463.html