python3 使用相对路径 import模块

目录结构

.
├── 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 test.py的方式

这时,在根目录下执行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

所以,应该一个‘.’是上一级目录,两个'.'是上两级。意思是把上一级目录加入搜索路径。

用python -m test的方式

这种方式下,如果我的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】

你可能感兴趣的:(Python)