Python的相对导入问题
最近运行一个工程时发现在单独执行包含以下相对导入的py文件时报出错误:“ImportError: attempted relative import with no known parent package”,但在运行整个工程时并没有报出关于相对导入的错误。关于这个问题出现的原因搜索了一些资料,在python绝对导入和相对导入详解-简书中找到答案。
from ..registry import BACKBONES
1.出现这种情况的原因:
在相对导入情况下,一个模块必须有包结构且只能导入它的顶层模块内部的模块。而当一个模块被直接运行时它自己就为顶层模块,不存在层次结构,所以找不到其他的相对路径,所以如果直接运行一个包含相对导入的.py文件就会报错。
2.Python Import简介:
(1)加载.py文件的两种方式:
1)作为top-level脚本:
作为top-level脚本指的是直接运行脚本文件(如执行:python file1.py),有且只能有一个top-level脚本,就是被执行的file1.py文件;
2)作为module:
作为module载入指的是执行 python -m myfile,或者在其它.py文件中用 import 语句来加载。
当一个 py 文件被加载之后,它会被赋予一个名字保存在 __name__ 属性中:如果是作为top-level脚本载入,那么名字就是 __main__;如果是作为module载入,名字就是把它所在的 packages.subpackages和文件名用 . 连接起来。
(2)Python Import的搜索路径:
1)在当前目录下搜索该模块;
2)在环境变量 PYTHONPATH 中指定的路径列表中依次搜索;
3)在 Python 安装路径的 lib 库中搜索。
(3)Python import 的步骤:
python所有加载的模块信息都存放在 sys.modules结构中,当import一个模块时,会按如下步骤来进行:
1)如果是import A,检查sys.modules中是否已经有A,如果有则不加载,如果没有则为A创建module对象,并加载A;
2)如果是from A import B,先为A创建module对象,再解析A,从中寻找B并填充到A的 __dict__ 中。
3.绝对导入简介:
绝对导入的格式为:
import A.B
from A import B
在绝对导入情况下一个模块只能导入自身的子模块或和它的顶层模块同级别的模块及其子模块。因此前面提到含有相对导入的模块不能被直接运行的情况,实际上含有绝对导入的模块也不能被直接运行,要运行包中包含绝对导入和相对导入的模块,可以用 python -m A.B.C 告诉解释器模块的层次结构。
相对导入可以避免硬编码,对于代码维护友好;绝对导入可以避免与标准库命名的冲突(实际上也不推荐自定义模块与标准库命令相同)。