关于python路径的问题思考
我相信你肯定遇到过这样的报错
Traceback (most recent call last):
File "main.py", line 549, in <module>
os.chdir(os.path.dirname(__file__))
FileNotFoundError: [Errno 2] No such file or directory: ''
这还要从python的路径问题说起
首先我们了解一下几个重要的概念

这里的 Desktop 指的是运行路径
寻找python 脚本的方式是相对路径寻找
__file__ 变量值为 path_test/test.py
知道这些我下面具体说 运行路径不同 会导致的问题
运行路径不同导致的问题
举一个简单的例子

在这个项目中有一个 1.txt 里面包含 Hello world字符串, 这段程序就是简单的寻找然后并输出,正常是可以输出的像这样在 sublime 中运行,得到结果:

而我们以另一种方式运行:

这样就会提示找不到这个文件,为什么会有这样的问题?
这里出现这种状况的原因主要是因为运行路径不同,而寻找相对路径的 1.txt 文件也就不同。
第一种寻找的 1.txt 真正路径是在 /home/wshuo/Desktop/path_test/1.txt
而第二种寻找的 1.txt 的真正路径是在 /home/wshuo/Desktop/1.txt 这当然会找不到了
这是因为 sublime 运行脚本的时候首先会将脚本存在的路径作为运行路径, 而第二种在终端运行的时候,会把当前所在的路径作为运行路径(我所在的是 Desktop)
下面我简单写一个例子来证明以上两点说法:


os.getcwd() 这个路径可以获取到当前的路径(也就是程序运行的路径)
运行路径不同找不到文件的解决方案
- 第一种你可以把 修改
txt文本文件改为绝对路径,显然这不是好的解决办法,因为代码不一定存放在什么地方,写成绝对路径寻找txt文件绝对是很傻的解决方案 - 更改运行的路径, 无论在什么路径运行都更改到项目路径下运行,这样无论 整个项目存放在什么地方都可以找到
txt文件了
那么如何更改我们的运行路径呢?
我猜大部分都是这样写的
import os
print(__file__)
path = os.path.dirname(__file__)
print(path)
os.chdir(path)
print(os.getcwd())
with open('1.txt') as f:
s = f.read()
print(s)
__file__ 的意思是 寻找这个脚本的路径+这个脚本文件的名字(可以是绝对路径寻找或相对路径寻找)
os.path.dirname 这个函数可以取出文件所在的路径
os.chardir 更改运行路径,下面我再使用这两种方式运行这段代码
所以上面代码的作用就可以解决 无论运行路径是否在脚本所在的路径都可以更改为脚本所在的路径


可以看到就算运行路径不在项目路径也不会报错了
更改运行路径导致的其他问题
但是问题真的就解决了吗?
下面我们换一种运行方式来运行
可以看到,更改完的代码进入项目路径运行反而会出错,而我们也可以看到 __file__ 变为了 test.py
这里报错是因为 __file__ 没有路径了完全就是一个文件名字了,所以肯定就获取不到他的父级目录了,而这段代码为什么在 sublime 运行的时候没有报错? 不应该他们运行的路径都是项目路径吗?
我们来看另一种运行方式(可能看到这里你已经懵逼了,但是其实我后面会做一个总结看完总结在看这些一下子就清晰明了了)

可以看到这里我们又没有报错了,因为这里我们寻找这个脚本文件是绝对路径寻找的!
前面我一直再说运行路径 不同导致的问题,这里引入一个新的概念:寻找脚本的方式 绝对路径寻找 和相对路径寻找
python运行方式分类
| 运行媒介 | 运行路径 | 寻找脚本的方式 |
|---|---|---|
| ide 运行 | 文件所在路径 | 绝对路径寻找 |
| 双击脚本文件 | 文件所在路径 | 绝对路径寻找 |
| cmd 或终端运行 | 不确定,看当前所在的路径 | 绝对路径寻找或相对路径寻找 |
可以看到 在终端或 cmd 中运行脚本的时候是最灵活的了,而我们可以以相对路径寻找和绝对路径寻找运行脚本, 运行路径也可以随着当前所在的路径不同而不同,所以用os.chdir上面修改过的代码可以在
| 运行路径 | 寻找脚本的方式 |
|---|---|
| 任意 | 至少有一级父级目录的相对路径寻找或直接的绝对路径寻找 |
这种条件下运行成功,因为如果进入项目路径下运行的话就必须有至少一层父级路径可以提供,否则获取不到父级路径,也就更改不了运行路径(报错是在获取不到父级目的地方报错)
知道报错原因,你也可以在项目路径这样运行脚本
wshuo@wshuo-Aspire-F5-572G:~/Desktop/path_test$ python3 ../path_test/test.py
Hello world!
这样也不会报错,就是退到上级目录然后在进入项目目录运行,这样就可以获取到文件所在的目录了,但是很傻,我们又不能确定用户会不会在文件所在目录运行这个脚本,更不会确定用户会不会以这样的方式运行脚本
最终的解决办法
- 做一个简单的容错处理
import os
try:
os.chdir(os.path.dirname(__file__))
except:
pass
with open('1.txt') as f:
s = f.read()
print(s)
这种解决方案肯定包含了所有情况,因为只有当 运行路径为 项目路径时 且python 后面只有 test.py 这个文件名的时候 才会报错,但在这种情况下根本不需要考虑更改运行路径的问题, 因为运行路径已经是 项目路径了,肯定是可以找到 1.txt 文件的
- 用
os.path.abspath处理一下再获取脚本所在路径
import os
os.chdir(os.path.dirname(os.path.abspath(__file__)))
with open('1.txt') as f:
s = f.read()
print(s)
这种解决方案也是不管 __file__ 这个变量是只是一个文件名经过获取绝对路径都可以变成绝对路径+文件名 的形式, 这样再获取脚本所在的路径肯定也不会报错的
关于python路径的问题思考的更多相关文章
- Mac Python路径总结
Mac 下Python 可以多版本的并存,并且Python的目录也有好几个,不过总体来说,Mac 自带的有python 还是比较方便的 Mac 系统自带的又Python ,可能Python版本需要更新 ...
- 沉淀,再出发:python爬虫的再次思考
沉淀,再出发:python爬虫的再次思考 一.前言 之前笔者就写过python爬虫的相关文档,不过当时因为知识所限,理解和掌握的东西都非常的少,并且使用更多的是python2.x的版本的功能,现 ...
- Python开发环境Wing IDE设置Python路径详解
在使用Wing IDE的时候,Python源代码取决于PYTHONPATH(无论是外部或通过内部改变sys.path系统设置),用户需要将路径设置到Wing IDE中. 这个值可以从项目菜单和工具栏的 ...
- Spring中统一相同版本的api请求路径的一些思考
Spring中统一相同版本的api请求路径的一些思考 问题场景 当我们在实际开发中,可能会遇到开发相同同版本的api, 假设相同版本的api请求路径为/v1/functionA,/v1/functio ...
- python - 路径处理 和 模块导入
# -*- coding:utf-8 -*- '''@project: jiaxy@author: Jimmy@file: study_模块导入.py@ide: PyCharm Community E ...
- pycharm怎么修改python路径
今天安装Django的时候遇到了python版本冲突,找不到python路径,所以又重新安装了一个python3.6.5 安装完之后,突然发现自己的pycharm是之前Anaconda的3.5版本,那 ...
- python路径写入注册表,导入三方模块win32
python在安装第三方模块时候,需要将python的路径写入注册表,否则会提示 'python version 3.8-32 required,which was not found in the ...
- 查找默认安装的python路径,并输出到 FindPythonPathX_output.txt
在python程序设计教学中,在汉化IDEL时.为PyCharm项目设置解释器时,经常需要查找python安装路径.对老手来说很简单,但对很多刚开始学习编程的学生来说,则很困难.所以,编写了一个批处理 ...
- python 路径操作工具 pathlib,比 os 模块好用太多
在 python 当中,如果你想控制路径,基本上绕不开 os.path.我希望看完这篇文章以后,熟练使用 python 的你能立刻开始使用 pathlib 模块,一刻也不要耽误. pathlib 相对 ...
- Python路径总结
Windows下文件路径的分隔符是'\'反斜杠,文件路径也是一个字符串,牵扯到'\'在Python字符串中存在转义的情况,就对这个问题做一个探究. Python字符串中要使用'\'时有两种方法: 使用 ...
随机推荐
- [机器学习]-分类问题常用评价指标、混淆矩阵及ROC曲线绘制方法
分类问题 分类问题是人工智能领域中最常见的一类问题之一,掌握合适的评价指标,对模型进行恰当的评价,是至关重要的. 同样地,分割问题是像素级别的分类,除了mAcc.mIoU之外,也可以采用分类问题的一些 ...
- 万星开源项目强势回归「GitHub 热点速览 v.22.38」
本周霸榜的 GitHub 项目多为老项目,比如:老面孔的 theatre 凭借极其优秀的动画功底连续三天霸榜 TypeScript 类目.借 Figma 被 Adobe 收购之风,又出现在 GitHu ...
- 安装配置docker&maven环境
原文视频:(https://blog.sechelper.com/20220919/code-review/docker-maven-install-guid/) Docker是什么 Docker ...
- Object.keys的‘诡异’特性,你值得收藏!
先从'诡异'的问题入手 例1: 纯Number类型的属性 const obj = { 1: 1, 6: 6, 3: 3, 2: 2 } console.log('keys', Object.keys( ...
- 使用Jumpserver堡垒机管理MySQL应用
第一步,添加系统用户 资产管理,系统用户,创建<数据库协议>MySQL 用户名和密码填写实际可以访问数据库的用户名和密码 第二步,添加应用 应用管理,数据库 主机和端口填写可以访问数据库的 ...
- 文档的CURD
Index方式,需要指定ID 如果ID不存在,创建新的文档,状态是created 如果ID存在,会先删除现有ID的文档,然后创建一个新文档,ID数加1,状态是updated PUT test/_doc ...
- C#.NET ORM 如何访问 Access 数据库 [FreeSql]
最近很多 .net QQ 群无故被封停,特别是 wpf 群几乎全军覆没.依乐祝的 .net6交流群,晓晨的 .net跨平台交流群,导致很多码友流离失所无家可归,借此机会使用一次召唤术,有需要的请加群: ...
- 制造业数字化转型,本土云ERP系统如何卡位?
去标准化,主打个性化,方可在制造业数字化转型中大放异彩,本土云ERP要想获得青睐成功卡位必须坚持这个原则.为什么这么说?就连某头部ERP厂商都倡导一个观念"Rise With.......& ...
- 微信小程序实现与登录
一.小程序的实现原理 在小程序中,渲染层和逻辑层是分开的,双线程同时运行,渲染层和逻辑层这两个通信主体之间的通讯以及通讯主体与第三方服务器之间的通信,都是通过微信客户端进行转发.小程序启动运行两种情况 ...
- HDU2844 Coins(多重背包)
多重背包就是每种物品有数量限制时求解最大价值. 如果一种物品数量和重量之积超过背包容量,可视为完全背包:其余情况通过二进制拆分,将几个数量的物品看成一个,转化为01背包求解. 按照这种思路代码是这样的 ...