.
├── apt_root.py
├── __init__.py
├── mod/
└── test.py
└── __init__.py
└── sub/
└── test.py
└── __init__.py
任务一:在mod/test.py中import 上级目录下的apt_root.py
任务二:在mod/test.py中import 上级目录的sub/test.py
【为什么题目限定python3的import?】
因为网上能搜到的PEP都是python2的。例如PEP328。但是据我观察,python2和python3的import规则不同。
【绝对路径他不香吗,为什么限定用相对路径import模块?】
通过绝对路径引用模块,容易造成在后续改变代码结构,或者文件改名时,修改工作多的问题。而相对路径没有这个问题
写这篇文章的一个出发点,是我发现import并没有很简单,至少对我造成了很多混乱,因此在这里进行分享,希望能上面两个任务能覆盖所有困难情况。首先一个混乱,是用不同方式执行test.py,其中的import能不能找到对应module是不同的。
这时,在根目录下执行python mod/test.py ,
或者 进入mod子目录再执行python test.py的效果是一样的。
用网上查到的这些方式都会报错:
from . import apt_root
# 或者
from .. import apt_root
# 或者
from ..apt_root import *
我测试成功的写法是这样:
import sys
sys.path.append(".")
import app_root
所以,应该一个‘.’是上一级目录,两个'.'是上两级。意思是把上一级目录加入搜索路径。
这种方式下,如果我的import是这样:
import app_root
(和直接python xxx.py不同)在不同目录下运行,会有不同效果!
一:在根目录下:python -m mod.test——运行成功
二:先进入mod子目录,再python -m test——运行失败
如果要运行成功,则应该这样:
sys.path.append("..")
import app_root
(又一个造成混乱的)python -m xxx时,把上级目录加入搜索路径,要用"..",这和python xxx.py时,用"."代表上级目录不同!
原因是python -m方式,会把当前运行命令的路径添加至sys.path。参见[python]自问自答:python -m参数?
所以,这种方法下,一定要结合当前运行命令的路径+默认sys.path中搜索路径+代码中sys.path.append新增路径,才能判断import是否能成功。
容易造成混乱的地方:
1.相对路径的使用不能用from .. import XX,而要用sys.path.append(“..”)
2.python -m xxx和python xxx.py对import的写法中上级目录表示不同,前者用两个点,后者用一个点;
3.python -m xxx中import搜索路径与当前执行命令的目录相关;
python xxx.py与当前执行命令的目录无关
【欢迎关注我的微信公众号:人工智能Beta】