一、绝对导入
project/
│── manage.py
│
└── pro/
│ │── admin.py
│ │── model.py
│ │── test.py
│ └── view.py
│
└── crm/
│── settings.py
└── surround.py
1.1 需要导入的模板在同一文件夹中
比如admin.py调用test.py模板,可以在admin.py中直接执行:
import test
因为python解释器查找模块时会找同一文件夹,所以不用导入路径名。
1.2 需要导入的模板在当前文件夹的子文件夹中
比如 manage.py调用setting.py模板,可以在manage.py中直接执行:
from crm import setting
无需加其他路径说明,因为 crm 也是一个模块(模块的集合)。
1.3 需要导入的模板在父文件夹中
比如admin.py想调用surround.py模板(在admin.py父文件夹project下),因为解释器找模块只会去本文件夹及本文件夹的子文件夹去找,不会去父文件夹找,为什么?试试看,先在admin.py中执行:
import sys
print(sys.path)
当一个的模块被导入的时候,解释器首先寻找具有该名称的内置模块。如果没有找到,然后解释器从 sys.path 变量给出的目录列表里寻找该模板。所以输出结果可以看到是一个路径列表,其它路径不需要看,只看第一项 :
'c:\\xxx\\project\\pro'
说明解释器就是从 pro文件夹开始往下找,而surround.py是在 project/crm文件夹下,显然是找不到的。
- 解决方法,在admin.py中执行:
import sys
sys.path.append(r'c:\xxx\project\crm') # 方法一
# sys.path.append('c:\\xxx\\project\\crm' ) # 方法二
# sys.path.append('c:/xxx/project/crm') # 方法三
import surround
手动把相应的路径添加到 sys.path 中就可以了,这样导入就相当于可以从添加的相应路径开始往下找模块了。可以找到,结果也不会报错。
二、相对导入
在涉及到相对导入时,package(包) 所对应的文件夹必须正确的被python解释器视作 package(包),而不是普通文件夹。否则由于不被视作package(包),无法利用package之间的嵌套关系实现python中包的相对导入。
文件夹被python解释器视作 package(包) 需要满足两个条件:
- 文件夹中必须有 __init__.py 文件,该文件可以为空,但必须存在该文件。
- 不能作为顶层模块来执行该文件夹中的py文件(即不能作为主函数的入口,也不能直接执行含有相对导入的py文件)。
project/
│── __init__.py
│── manage.py
│
└── pro/
│ │── __init__.py
│ │── admin.py
│ │── model.py
│ │── test.py
│ └── view.py
│
└── crm/
│── __init__.py
│── settings.py
└── surround.py
admin.py想调用surround.py模板,如果想用相对路径,在admin.py中执行:
from ..crm import surround
会报错:‘ImportError: attempted relative import with no known parent package’,因为没有满足上面的条件2。既然你在admin.py里执行了相对导入,那就不要把admin.py当作入口程序直接运行,可以通过上一级的manage.py调用 admin.py。
然后在manage.py中执行:
from pro import admin
又会报错:‘ValueError: attempted relative import beyond top-level package’,这是因为 from ..crm import surround 这句代码会把manage.py所在的这一层 project 文件夹视作package(包),但实际上它不是,因为package(包)不能是顶层入口代码,若想不出错,只能把manage.py往上再移一层。
package/
│── __init__.py
│── manage.py # from project.pro import admin
│
└──project/
│── __init__.py
│── manage.py
│
└── pro/
│ │── __init__.py
│ │── admin.py # from …crm import surround
│ │── model.py
│ │── test.py
│ └── view.py
│
└── crm/
│── __init__.py
│── settings.py
└── surround.py
再执行manage.py就不会报错了:
from project.pro import admin
注意:虽然python支持相对导入,但对模块间的路径关系要求比较严格,处理不当就容易出错,不建议使用。
参考:
https://www.cnblogs.com/schut/p/8436138.html
https://www.cnblogs.com/buptldf/p/4972926.html