7

当我这样做时,我__init__.py会进行检查from myprojects.something import blabla

今天我开始使用pyzmq,我想看看幕后发生了什么。所以我浏览了 github 中的代码,我发现(对我来说)__init__.py那里有一些我无法解释的奇怪用法。

例如zmq/core/__init__.py. 添加zmq.core.__all____all__值有什么意义zmq.core.constants, zmq.core.error, zmq.core.message, etc.

zmq/__init__.py我看到最后

__all__ = ['get_includes'] + core.__all__

whereget_includes是一个函数,它基本上返回一个列表,其中包含模块目录和父目录中的 utils 目录。

那有什么意义呢?这样做有什么__init.py__收获?

4

1 回答 1

13

__all__是当有人from module import *按照此处记录的那样进行操作时。

唯一的解决方案是包作者提供包的显式索引。import 语句使用以下约定:如果包的__init__.py代码定义了一个名为 的列表 __all__,则当遇到 from package import * 时,它将被视为应导入的模块名称列表。当包的新版本发布时,由包作者保持这个列表是最新的。包作者也可能决定不支持它,如果他们没有看到从他们的包中导入 * 的用途。例如,该文件sounds/effects/__init__.py可能包含以下代码:

__all__ = ["echo", "surround", "reverse"]

这意味着from sound.effects import *将导入声音包的三个命名子模块。

一个用途__all__是包构建者的工具,允许他们以适合他们的方式构建包,同时方便用户。特别是在 pyzmq 的情况下,它可以让您编写如下代码:

import zmq
print zmq.zmq_version()

而不必使用完整的点模块名称:

print zmq.core.version.zmq_version()

pyzmq 的包设计者正在使用__all__将命名空间元素从嵌套模块提升到其命名空间的顶层,这样用户就不会被他们的包结构所困扰。

于 2012-09-20T22:39:12.517 回答