学Python有5个月了,出了一个“未找到模块”的问题,竟然不知道是由于工作目录不对导致的,你们有没有遇到过这样的人?
我遇到了,是我运气太好了,还是说这本来就是正常现象。
进入正题,一起来看一下这个事情是怎么发生的。
我们的任务是用BERT做实体识别和关系提取,语料已经用brat标记好了。就只需要将标记文件处理为训练预料格式,再转换为token加载到内存中,喂给模型进行训练,最后,就等着模型训练完成就行了。
整个过程应该都是比较清晰的,所有的程序我之前都写好了的,就只需要执行一下,观察过程中损失收敛的情况就完事了。
然而问题来了,就是这个“执行”步骤居然把这个小伙伴给难倒了,竟然没有成功运行起来,还说“是不是环境缺少什么包!”
我了解情况后,心中真的是五味杂陈,不就是“工作目录”不对的问题吗!
小伙伴的cmd目录为
c:\users\xxx
而程序的目录在
d:\myapp\subdir\my_predict.py。
小伙伴执行语句输的是
虚拟Python路径\scripts\python.exe d:\myapp\subdir\my_predict.py
然后得到了以下提示
ModuleNotFoundError: No module named 'utils'
在出现这个问题时,小伙伴给我了一条消息,你们猜猜,他说的是什么?
“先前那个虚拟环境包不全”,这就是小伙伴发的消息。
我想但凡有点Python基础的朋友,都能看出来这是什么问题,应该就不会这么问,早就自己解决了,我也不知道发生了这个问题。
我回复小伙伴道,应该先进入
d:\myapp
这个目录,然后再执行命令
虚拟Python路径\scripts\python.exe subdir\my_predict.py
这样不就好了吗?
为什么会出现这种想都想不到的问题呢?
抱歉,除了在这上面付出的精力太少之外,我想不到还有什么其他原因。
当然,也许是我已经失去了初心,不记得自己也曾犯过这种错误了吧!
有一次,我把在本地已经调试好的程序部署到服务器,本以为没什么难度,结果得到的就和这个小伙伴一样的结果,ModuleNotFoundError。
为何如此呢?
原因也还是和上面小伙伴一样,不同的是我已经在执行文件所在目录,我要引用上级目录的一个文件,没有成功,就出现了找不到模块的问题。
为何在IDE(开发工具)中遇不到呢?
因为在IDE中,无论你要运行哪个目录中的Python文件,IDE就已经帮我们把工作目录定位到项目的根目录了,所以遇不到这样的问题。
那么,除了定位到项目的根目录以外,还有没有其他办法可以解决这个问题呢?
答案是有。
可以在import的时候添加双点号。
比如,from .. import utils 就表示将上级目录中的utils模块导入进来。
那如果我要导入上上级的utils呢?
对不起,不是 from .... import utils,也不是from ../.. import utils,这两种写法都不对。
正确的做法是这样的,先获取当前文件的父目录的父目录。
parent_parent_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
再将获取的目录加入当前查找路径。
sys.path.append(parent_parent_dir)
然后,就可以正常导入了 import utils 就行了。
当然,你也可以使用绝对路径来引入当前查找路径。
sys.path.append(r'd:\mywork\common\utils.py')
然后你就可以正常导入utils了。
是不是很神奇,原来还有这么多方法可以导入模块。
但是,还是建议在工作目录去运行你的python文件吧,毕竟这样是最通用的,不用改来改去。
当然,你还要加一条命令:
set PYTHONPATH=%PYTHONPATH%;.\
这个才是最重要的。