Python 相对导入 碎碎念
调试老代码每个人都会遇到,像python这种脚本向的语言,配置环境换台电脑就不一样了,尤其是库内之前有人上传过配置文件或者在代码里有像sys.append硬路径的情况.
这边先暂时分享一篇python的相对路径import和原理:
假设有如下层次包目录
project/ __init__.py mypackage/ __init__.py A/ __init__.py spam.py #* print("In spam") *# grok.py #* print("In grok") *# C/ __init__.py hello.py #* print("In hello") *# B/ __init__.py bar.py #* print("In bar") *# run.py main.py
相对导入语法:
from . import module from .. import module from ... import module
相对导入与模块__name__有关
- run.py作为顶层模块执行导入A.spam时
- run.py的__name__ 等于 __main__
- spam.py的__name__ 等于 A.spam
- A成为顶层的包,所以相对导入最多只能访问到A,A之外的层次结构是不可见的
- main.py作为顶层模块执行导入mypackage.A.spam是
- main.py的 __name__ 为 __main__
- spam.py的__name__ 为 mypackage.A.spam
- mypackage成为顶层包,相对导入作用域扩大,B/包对spam.py可见
相对导入只适用于包中的模块,顶层的模块中将不起作用
- 如果将run.py当作顶层执行模块
- A/ 和 B/ 将成为 toplevel package 顶层包 A/中的模块不能用相对导入来导入B/包中的模块,因为不能越过顶层包。
- A/、B/ 包中的目录可以导入本包中及以下的模块
- 如果将main.py当作顶层执行模块
- mypackage/成为顶层包,A/可以访问到B/包,不会出现 ValueError: attempted relative import beyond top-level package
例子
## run.py (run.py当作顶层执行模块,即 python run.py) #----------- import A.spam ## spam.py #-------------- from . import grok # ok from .C import hello # ok from ..B import bar # !Err ##—— ValueError: attempted relative import beyond top-level package print('In spam') ## main.py #------------ import mypackage.A.spam ## spam.py #------------- from ..B import bar # ok print('In spam')
reference:
https://www.cnblogs.com/linkenpark/p/10909523.html