python模块绝对引用和相对引用

python项目中的模块引用问题,是一个比较复杂的问题,无非是绝对引用,相对引用,看起来似乎很简单,但在实践中,总是会出现一些“莫名其妙”的错误,但解决起来倒也方便,import语句的写法多试验几次也就可以搞定了,关于这方面,很少有文章全面深入的讨论,我也是在这块吃过几次亏后,痛定思痛,决定认真研究一下。本文所使用示例在python3.7环境下顺利通过,如果文中观点有错误之处,请各位看官不吝赐教。

入口脚本

首先明确一点,一个项目的入口脚本,或者说启动脚本,必须放在项目的根目录下,启动脚本所在的目录,将被加入到sys.path里,而我们在脚本里使用import引入模块时,会根据sys.path里的目录逐个进行查找,这一点很关键,后面会用到。

pypackage/
├── __init__.py
├── log.py
├── run.py
├── utils
│   ├── fileutil.py
│   └── __init__.py
└── view
    ├── __init__.py
    ├── one.py
    ├── two.py
    └── view2
        ├── four.py
        ├── __ini__.py
        └── three.py

run.py 作为项目的启动脚本,放在了根目录下,它可以引用项目里的任意模块。

绝对引用

从层级上看,log.py也在根目录下,four.py 在view/view2目录下, 那么 four.py脚本里可以引入log模块么?答案是肯定的,因为启动脚本所在的目录,将被加入到sys.path里,因此在four.py 里可就可以这样写

import log

受此启发,fileutil 也可以引入four模块

from view.view2 import four

这里的关键就在于启动脚本所在的目录被加入到sys.path里

相对引用

如果我想在one.py 里引用two模块,除了绝对引用外,还可以使用相对引用

from view import two    # 绝对引用
from . import two       # 相对引用

如果我想在one.py 里引用fileutil 模块,讲道理的话,下面两种方法都可行

from utils import fileutil  # 绝对引用
from ..utils import fileutil  # 相对引用  实测不可行

一个. 表达式当前目录, 两个 .. 表示上一级目录,那么 from ..utils import fileutil 本应该也可行,但实测却发现无法引用,所以,遇到这种莫名其妙的问题,我建议你使用绝对引用,避免使用相对引用

扫描关注, 与我技术互动

QQ交流群: 211426309

加入知识星球, 每天收获更多精彩内容

分享日常研究的python技术和遇到的问题及解决方案