繁体   English   中英

命名空间与常规包

[英]Namespace vs regular package

命名空间 Python 包(没有__init__.py )和常规 Python 包(有__init__.py )之间有什么区别,尤其是当__init__.py对于常规包为空时?

我很好奇,因为最近我一直忘记在我制作的包中制作__init__.py ,而且我从未注意到任何问题。 事实上,它们的行为似乎与常规包相同。

编辑:命名空间包仅从 Python 3.3 支持(见 PEP 420 ),所以自然地,这个问题只适用于 Python 3。

命名空间包

Python 3.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 ,则 PYTHONPATH ( sys.path ) 中的第一个是使用的。

__init__.py曾经需要使目录成为一个包

命名空间包是没有__init__.py包。

对于一个简单包的示例,如果您有一个目录:

root
+--package
   +--file1.py
   +--file2.py
   ...

虽然您可以在package目录中独立运行这些文件,例如使用python2 file1.py ,但在 Python 2 下,您将无法将文件作为模块导入到根目录中,例如

import package.file1

会失败,为了让它工作,你至少需要这个:

package
  +--__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 文件,您可以将__init__.py完全留空。

使用 pkgutil 使用__init__.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 中得到了更彻底的解决

另请参阅此处有关设置工具和命名空间的更多讨论:

http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages

从 Aaron 和PEP420读取链接,似乎命名空间包和常规包之间的根本区别,除了常规包可能在__init__.py包含各种初始化代码的明显区别之外,命名空间包是一个虚拟包其内容可以沿着 Python 的查找路径分布在不同的地方。

例如,给定

a/foo/bar.py
b/foo/baz.py

如果ba都在 Python 的路径中,则可以自由导入foo.barfoo.baz

当然,这就引出了一个问题,如果不需要__init__.py ,那么在所有其他条件相同的情况下,制作常规包还是命名空间包更好,但有点跑题了。

  1. 拥有__init__.py使得你可以在别处导入该包。
  2. 此外, __init__.py文件可以包含每次加载模块时要执行的代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM