记一次os.path的采坑过程
BUG 初现
今天跑模型。在准备数据集这一环节,遇到一个很诡异的bug。。。
同样的一个脚本(暂且命名为 A.py),在 PyCharm 中,右键点击 “运行”,是可以正常跑起来的,如下所示:
但是,当我使用服务器命令行运行 "python A.py" 时,离离原上谱的事情出现了,它没有任何输出,而且也不报错,就刷的一下退出了(确定执行命令的路径,就是 A.py
所在路径)...就像这样
WHY?遂以为是代码出 bug 了,什么地方函数调用错了才导致直接退出了,然后从第一行开始到最后一行,加了四个 print
(脚本第一行一个,最后一行一个,中间两个),然后,更加诡异的事情发生了,四个 print
全部输出,但是代码就是不执行,也不报错
遂去问 ChatGPT,AI 说有可能是 PyCharm 本地的 python 解释器版本和服务器上版本不一致导致的,或者是第三方库版本号不一致导致不兼容,然后发现.....(这里第三方库太多就不放图了,反正两边所有库版本号均一致)
奇了怪了???
这个时候,往往最朴素的办法就是 print
大法,将代码中所有可能出错的变量都打印出来看看
然后,真的定位到诡异之处了
首先,这是项目结构,黄色框为出现 bug 的脚本:
代码中有一行是获取当前项目根路径的绝对路径,代码时这样写的:
ROOT_DIR = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
这行命令看似没什么毛病,但是当我使用 print
输出时,发现 ROOT_DIR
为 None
,这是为什么?右键运行时, ROOT_DIR
是有值的,但是换到命令行就为 None
了?
探究原因
- 首先探究一下
__file__
是什么?
顾名思义。他代表的应该就是当前的脚本文件,在出错的脚本中加上如下代码,输出一下
import os
print(__file__)
使用PyCharm 右键运行,它输出的是当前文件的绝对路径:
而当使用命令行运行时,他只输出了文件名(即当前文件的相对路径)
此时应该已经可以发现问题了,出问题的哪一行代码是这样写的:ROOT_DIR = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
,他获取的就是当前文件的向上两级父路径(项目根路径)
当使用 PyCharm 运行时,很正确的获取到的向上两级父路径 G:/study/No1/BiShe/ISBNet
,但是当使用命令行时,它的父级目录都不存在,更别说两级父目录了,所以这就导致了没有获取到 ROOT_DIR
,接下来的数据集也自然无法获取到,所以代码直接没有什么反应就执行完了
2.问题找到了,怎么改?
现在问题出在:命令行模式下获得的是脚本文件相对当前命令行执行目录的相对路径,那么只要能在命令行模式下获得脚本的绝对路径不就行了?
遂想到 python 有一个函数叫做 abspath
,听名字也是获得绝对路径,使用它配合 __file__
与 path.join
应该就可以了
先测试一下,运行代码:
import os
print(os.path.abspath(__file__))
右键运行和命令行运行的结果也都一样,都是当前脚本的绝对路径
然后配合 os.path.join()
,从当前路径向上寻找两级目录就可以找到项目根路径的绝对路径了
ROOT_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
修改完成后,再次将脚本上传服务器,已经可以正常运行了,BUG 解决
总结
以后在 python 中操作路径时,最好使用 os.path.abspath