为什么Python需要在包中使用__init__.py文件?

5
我知道Python需要`__init__.py`文件才能将目录识别为Python包,这样我们就可以将子模块导入到程序中。我可以看到它与类的相似之处,以及如何使用`init`来执行必要的代码。
然而,在Python文档中,这行代码让我感到困惑,
“这是为了防止具有常见名称(例如string)的目录无意中隐藏在模块搜索路径后面出现的有效模块。”
请参见https://docs.python.org/2/tutorial/modules.html#packages
能否有人澄清一下这个问题?

你特别链接到Python 2,但你可能会对Python 3的命名空间包感兴趣,它们不能包含__init__.py。请参阅https://www.python.org/dev/peps/pep-0420/。 - cdarke
3个回答

7
文档已经非常清晰地说明了这一点 - 您的项目结构可能如下所示:
app
 - common
  - init.py
 - resources
 - string
 - src

如果Python将目录隐式地视为包,那么"string"目录可能会与Python内置的字符串模块(https://docs.python.org/2/library/string.html)产生名称冲突。这意味着在调用import string时,模块是不明确的。 __init__.py还添加了一些功能:在初始化包时执行其中的代码,因此可用于进行某种包设置。

4

这样做是为了防止常用名称的目录(例如"string")无意中隐藏在模块搜索路径后面的有效模块。

假设您有一个目录,用于学校工作,其中包括一些使用Python的内容。您有一个名为math的目录,用于存储与数学相关的文件。您还编写了一个Python模块,因此将顶级目录“school”添加到Python路径中,以便在任何地方都可以使用它。

School/    
   math/
      hw1.txt
      integrate.py
   MyPythonModule/
      __init__.py
      someClass.py
      someFunc.py

当你在使用Python并搜索MyPythonModule时,Python会打开目录。

然后它会看到和。如果你在Python程序中使用math,并且没有办法区分模块<../lib/site-packages/math/>和非模块<../School/math/>,那么Python会将你的文件<../School/math/>视为数学包;而不知道导致代码出错。


4
如果您有一个名为“string”的目录,但它不是一个包,并且在Python搜索模块和包的位置中(例如当前工作目录),当您执行import string时Python不应该尝试导入它。 __init__.py的要求让Python知道它应该继续前行而不是将该目录视为一个包。

谢谢,现在我完全明白了。 - Dirk Dunn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接