3

在浏览python 手册的 6.4 Packages 部分时,我遇到了以下行:

需要这些__init__.py文件才能使 Python 将目录视为包含包;这样做是为了防止具有通用名称(例如字符串)的目录无意中隐藏了稍后出现在模块搜索路径上的有效模块。

我知道__init__.py将目录标记为包含包是必需的,但我不明白prevent directories with a common name...from unintentionally hiding valid modules....

有人可以解释为什么__init__.py需要吗?

4

2 回答 2

10

假设您有一个项目,其中包含一个名为的目录math,其中包含一些数字数据。如果__init__.py不需要,那么当你这样做时import math,它会尝试导入该目录而不是真正的math模块。但是由于您的目录只包含数据而不是实际的 Python 代码,因此导入会失败。因此,即使您的目录根本不包含 Python 代码,您的math目录也会阻止您从标准库中导入真正的模块。mathmath

__init__.py就像一个确认,目录说“是的,我真的是一个 Python 包,而不仅仅是一个充满文件的目录。导入我是有意义的。” 任何不以这种方式“宣布”自己的目录都会被跳过,因为 Python 知道它们不能被导入。这很好,因为 Python 标准库的模块有很多通用名称(操作系统、数学、时间、符号、资源等)。如果没有这个__init__.py要求,您将永远无法将这些名称中的任何一个用于Python 路径上的任何目录——甚至无法存储与 Python 无关的数据或文件。

string在这种情况下,实际上并不是最好的例子。有一个名为的模块,string但现在它并不那么有用,因为它的大部分功能都可以作为str类型上的方法使用。但是,就像我提到的那样,还有许多其他具有通用名称的模块。

于 2013-01-03T22:05:35.627 回答
3

您的源代码树中可能有一个名为 string/ 的文件夹,其中包含本地化数据,但是当您尝试import string在代码中不使用__init__.py时,Python 将尝试导入此目录而不是标准库模块。虽然在某些情况下您可能想要隐藏标准库模块,但如果您碰巧使用名称为 http/、string/、os/ 等的目录,则意外发生这种情况将是有问题的。

于 2013-01-03T22:06:29.707 回答