当前位置 : 主页 > 编程语言 > python >

关于python路径的问题思考

来源:互联网 收集:自由互联 发布时间:2022-06-24
我相信你肯定遇到过这样的报错 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 : '' 这还要从

我相信你肯定遇到过这样的报错

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的路径问题说起
首先我们了解一下几个重要的概念
关于python路径的问题思考_绝对路径
这里的 ​​​Desktop​​​ 指的是运行路径
寻找python 脚本的方式是相对路径寻找
​​​__file__​​​ 变量值为 ​​path_test/test.py​​ 知道这些我下面具体说 运行路径不同 会导致的问题

运行路径不同导致的问题

举一个简单的例子
关于python路径的问题思考_绝对路径_02
在这个项目中有一个 ​​​1.txt​​​ 里面包含 ​​Hello world​​​字符串, 这段程序就是简单的寻找然后并输出,正常是可以输出的像这样在 sublime 中运行,得到结果:
关于python路径的问题思考_python_03
而我们以另一种方式运行:
关于python路径的问题思考_相对路径_04
这样就会提示找不到这个文件,为什么会有这样的问题?
这里出现这种状况的原因主要是因为运行路径不同,而寻找相对路径的 ​​​1.txt​​​ 文件也就不同。
第一种寻找的 ​​​1.txt​​​ 真正路径是在 ​​/home/wshuo/Desktop/path_test/1.txt​​​ 而第二种寻找的 ​​1.txt​​ 的真正路径是在 ​​/home/wshuo/Desktop/1.txt​​ 这当然会找不到了
这是因为 sublime 运行脚本的时候首先会将脚本存在的路径作为运行路径, 而第二种在终端运行的时候,会把当前所在的路径作为运行路径(我所在的是 Desktop)
下面我简单写一个例子来证明以上两点说法:
关于python路径的问题思考_相对路径_05
关于python路径的问题思考_相对路径_06
​​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​​​ 更改运行路径,下面我再使用这两种方式运行这段代码
    所以上面代码的作用就可以解决 无论运行路径是否在脚本所在的路径都可以更改为脚本所在的路径
    关于python路径的问题思考_python_07
    关于python路径的问题思考_绝对路径_08
    可以看到就算运行路径不在项目路径也不会报错了

    更改运行路径导致的其他问题

    但是问题真的就解决了吗?
    下面我们换一种运行方式来运行关于python路径的问题思考_绝对路径_09
    可以看到,更改完的代码进入项目路径运行反而会出错,而我们也可以看到 ​​​__file__​​​ 变为了 ​​test.py​​​ 这里报错是因为 ​​__file__​​ 没有路径了完全就是一个文件名字了,所以肯定就获取不到他的父级目录了,而这段代码为什么在 sublime 运行的时候没有报错? 不应该他们运行的路径都是项目路径吗?
    我们来看另一种运行方式(可能看到这里你已经懵逼了,但是其实我后面会做一个总结看完总结在看这些一下子就清晰明了了)
    关于python路径的问题思考_绝对路径_10
    可以看到这里我们又没有报错了,因为这里我们寻找这个脚本文件是绝对路径寻找的!
    前面我一直再说运行路径 不同导致的问题,这里引入一个新的概念:寻找脚本的方式 绝对路径寻找 和相对路径寻找

    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__​​​ 这个变量是只是一个文件名经过获取绝对路径都可以变成​​绝对路径+文件名​​ 的形式, 这样再获取脚本所在的路径肯定也不会报错的


    作者:Hello_wshuo​


    上一篇:python3实现AES加密
    下一篇:没有了
    网友评论