在 Python 中,多个模块的集合叫做包 (package) ,也就是说一个文件夹下嵌套着多个文件夹叫包。这个时候,包内部的文件的互相导入就需要相对导入了。如果还使用绝对导入,也不是不行,但是项目会变得难以维护,把最顶层文件夹改个名就跑不起来了。
但是要注意,下面这种不算包:
. ├── lib │ └── lib.py ├── func │ └── func.py └── main.py # 主文件
因为主文件所在的这个文件夹不算数,实际上它是两个独立的模块。所以,你不需要用到相对导入,正常玩就行了:
# 在 func/func.py 中: from lib import lib def solve(): lib.prt('func.py')
拉回正题,我们这次重点是讨论相对导入。
相对导入的目录标准格式是这样的:
. ├── main.py └── mypackage ├── A │ ├── grok.py │ └── spam.py └── B └── bar.py
mypackage 是一个包, A 、 B 都是子模块。
如果我们想要让 spam.py 从 grok.py 导入某个函数:
# mypackage/A/spam.py from . import grok # 或 from .grok import func
一个点就是同一目录下的导入。
但是我们大部分情况也是需要不同模块之间导入的。
比如说我们要在 bar.py 中导入 grok.py 中的某个函数:
# mypackage/B/bar.py from ..A import grok # from .. import A # from ..A.grok import func
这样一来,导入就只针对 A 和 B 了,不涉及 mypackage ,你可以随便迁移,反正都能跑起来。