背景:在PyCharm中写的Python脚本通过IDE运行正常,但是通过CMD或者终端运行就会报错module找不到,所以学习下Python的import机制是如何生效的是非常有必要的
import报错问题描述:
其中main.py是我们的启动脚本
1.通过Pycharm运行是OK的:
2.通过终端或者CMD运行报错找不到module:
模拟报错代码:
其中main.py是我们的启动脚本:
# coding=utf-8
from src import common
from src.packone import test1
test1.py是一个module:
# coding=utf-8
from ..packtwo import test2
from .. import common
在Pycharm中运行正常,在终端中运行报错:
简单的将main.py的位置移动到和src同层级,通过终端执行就正常了:
原因是什么?
我们先看下Python中import的机制:
- relative import
from . import yyy
from .xx import yyy
from ..xx import yyy
from ...xx import yyy
相对引入方式使用一个点号来标识引入类库的精确位置。与linux的相对路径表示相似,一个点表示当前目录,每多一个点号则代表向上一层目录。
- absolute import
from src.packone import test1
绝对引用通过package的绝对路径引入module,且路径要从最上一层的package写起。
这里有几个问题需要注意:
一、使用relative import的脚本不能直接启动,否则会报错:Attempt relative import in non-package。
原因是:
相对引入使用被引入文件的__name__
属性来决定该文件在整个包结构的位置,但是当python脚本被直接运行时,这个module的__name__
就被设置__main__
, 而不是module原来的name,这样相对路径就无法识别。
二、即使使用了绝对引用,启动脚本也要放在和top-level package同层级,如果放在topo-level的package下,在终端下运行会报错:No module named xxx
原因是:
1.Python通过import的模块搜索路径有:
- 程序主目录
- PYTHONPATH目录
- 标准链接库目录
- .pth文件目录(指python运行用户把有效的路径添加到模块搜索路径中去)
2.如果启动脚本放在src目录下:
2.1.程序主目录为src/,在这个目录下没有src这个module
2.2.PYTHONPATH目录下也不会有src这个module
2.3.标准链接库目录和.pth文件目录也不回搜索到src这个module
3.如果启动脚本放在src同级目录下:
程序主目录下即可搜索到src这个module,import便不会报错
网友评论