在Python中导入模块和__init__.py

28 投票
4 回答
35942 浏览
提问于 2025-04-16 17:07

我最近在了解 __init__.py 文件的作用。听说在包含模块的文件夹里需要一个空的 __init__.py 文件,这样才能导入这些模块。不过,我尝试把一个文件夹的路径添加到 PYTHONPATH(Windows 7 的环境变量)中。虽然这个文件夹里没有 __init__.py 文件,但我还是能从这个文件夹导入模块。你能解释一下没有 __init__.py 的情况下,怎么还能导入这些模块吗?

4 个回答

9

在你的模块目录中,有没有__init__.py文件的区别是:

当你一个空的 __init__.py 文件时,你可以通过下面的方式导入这个模块:

from dirname import MyModule

但是如果你没有 init.py 文件,你就不能直接导入这个模块,除非你把这个模块的路径加到 PYTHONPATH 里。在这种情况下,from dirname import MyModule 会失败,或者报错。

# 没有 init.py 的目录/模块结构

[root@Machine python]# cd NoInitModule/
[root@Machine NoInitModule]# pwd
/python/NoInitModule
[root@Machine NoInitModule]# ls -l
total 4
-rw-r--r--. 1 root root 44 Jan 16 07:02 ModuleX.py

# 有 init.py 的目录/模块结构

[root@Machine NoInitModule]# cd ../InitModule/
[root@Machine InitModule]# ls -l
total 4
-rw-r--r--. 1 root root  0 Jan 16 07:13 __init__.py
-rw-r--r--. 1 root root 49 Jan 16 07:12 ModuleY.py
[root@Machine InitModule]#

例子:

# 没有 init.py,使用 from dir import module 语句 - 不工作

[root@Machine python]# cat impomod.py
from NoInitModule import ModuleX

ModuleX.printBye()

[root@Machine python]# python impomod.py
Traceback (most recent call last):
  File "impomod.py", line 7, in <module>
    from NoInitModule import ModuleX
ImportError: No module named NoInitModule
[root@Machine python]#

# 没有 init.py,使用 import 语句 - 不工作

[root@Machine python]# vim impomod.py
[root@Machine python]# cat impomod.py
#from NoInitModule import ModuleX
import ModuleX

ModuleX.printBye()
[root@Machine python]# python impomod.py
Traceback (most recent call last):
  File "impomod.py", line 8, in <module>
    import ModuleX
ImportError: No module named ModuleX
[root@Machine python]#

# 没有 init.py,先把路径加到 PYTHONPATH,再导入模块 - 工作

[root@Machine python]# vim impomod.py
[root@Machine python]# cat impomod.py
import sys
sys.path.append('/python/NoInitModule')
print sys.path

import ModuleX
ModuleX.printBye()

[root@Machine python]# python impomod.py
Bye from Module X with no __init__.py
[root@Machine python]#

# 有 init.py,不用加路径,使用 from dir import module 语句 - 工作

[root@Machine python]# cat impXmod.py
import sys
from InitModule import ModuleY
ModuleY.printSeeU()
[root@Machine python]#

[root@Machine python]# python impXmod.py
See you from Module Y having __init__.py

# 有 init.py,不用加路径,使用 import 语句 - 不工作

[root@Machine python]# vim impXmod.py
[root@Machine python]# cat impXmod.py
import sys
#from InitModule import ModuleY
import ModuleY
ModuleY.printSeeU()

[root@Machine python]# python impXmod.py
Traceback (most recent call last):
  File "impXmod.py", line 3, in <module>
    import ModuleY
ImportError: No module named ModuleY

当然,子文件夹的问题也可以加到这里。

10

如果一个文件夹里有一个叫做 __init__.py 的文件,那么这个文件夹就变成了一个 。你之前理解的可能不太准确。一个包可以像一个模块一样被导入,而这个 __init__.py 文件里的代码会被执行,虽然这个文件通常是空的。包的作用是把多个模块放在一起,方便管理和使用,你可以通过以下方式来加载它们:

import package-name.module-name

包也可以嵌套在其他包里,这种情况很常见。你可以在你的 Python 软件目录下的 Lib 文件夹里找到很多这样的例子。

19

__init__.py 文件的作用是把一个文件夹变成一个 。这很有用,因为它可以帮助我们创建一种模块的层次结构,这样我们就可以使用像下面这样的导入语句:

import mymodule.cool.stuff

如果没有包,这种做法是行不通的。

撰写回答