sys.path 与 os.getcwd区分:代码运行中的路径问题

文章详细介绍了Python中获取当前工作目录的方法,如os.getcwd(),以及模块搜索路径sys.path的使用,包括如何处理找不到文件或模块的错误。通过实例展示了os.getcwd()、sys.path[0]、sys.argv[0]和__file__的区别,强调了它们在不同运行环境下的表现。此外,还讨论了如何解决模块导入问题,如添加路径到sys.path和创建__init__.py文件。
摘要由CSDN通过智能技术生成

获取当前工作目录

import sys

print(sys.path[0])

获取执行命令的位置

import os

print(os.getcwd())

python 代码运行路径问题

在下载使用别人的代码进行运行时,有时会遇到路径问题。将自己目前遇到的进行分类和总结。

主要分为两类:

import相关

open文件相关

问题的来源是:IDE和cmd的默认工作路径的差异,或模块搜索路径不同。(即可能是自己和对方使用的IDE的不同默认工作路径导致的。)

当前工作目录

文件读写等相关操作使用的基本路径。

通过函数os.getcwd()获得

通过函数os.chcwd()改变

os.path

功能:作为对路径进行操作的模块

注意:

在cmd下运行时:

文件组织:

folder

file.py

python folder/file.py :当前工作目录在父亲目录

python file.py : 当前工作目录在folder下
常见问题:

打开文件描述符时出错

找不到对应的文件

FileNotFoundError: [Errno 2] No such file or directory
解决

修改要读写的文件路径

系统搜索路径

sys.path

数据类型:字符串数组

功能:确定模块搜索路径

初始化:系统环境变量PYTHONPATH ,默认安装路径(比如在终端输入:export PYTHONPATH=$PYTHONPATH:/home/.../MinkLoc3Dv2)
常见问题:

import 模块时出错

需要导入的的代码不在sys.path中

ModuleNotFoundError: No module named
解决

将对应模块所在的路径加入到sys.path中。(比如在代码中加入:sys.path.append(‘/home/zs/project/github/minkloc3d/MinkLoc3Dv2’))

如果对应模块在子文件夹下,可以通过在子文件夹下创建 init.py文件解决。(相当于对子文件目录升级为模块)

附件资料

标题:os.getcwd()、sys.path[0]、sys.argv[0]和__file__的区别

os.getcwd()、sys.path[0]、sys.argv[0]和__file__的区别,终于弄清楚了

要分清这几个的区别与使用条件,实际测试一下是最准确的。

设计测试方法:

一个主模块用来运行,一个子模块用来被主模块调用
 
主模块路径: 

/Users/stephen/Documents/code/test_dir/01test

子模块路径:

/Users/stephen/Documents/code/test_dir/02test

运行模块的路径:

/Users/stephen/Documents/code/test_dir/01test/001_test

ok 现在编写两模块代码

子模块 submodule.py

    import os
    import sys
    def child_test():
    print('sub os.getcwd():{}'.format(os.getcwd()))
    print('sub sys.path[0]:{}'.format(sys.path[0]))
    print('sub sys.argv[0]:{}'.format(sys.argv[0]))
    print('sub __file__:{}'.format(__file__))
    if __name__ == '__main__':
    chid_test()

主模块 mainmodule.py

import os
import sys
import submodule
def main():
    print('main os.getcwd():{}'.format(os.getcwd()))
    print('main sys.path[0]:{}'.format(sys.path[0]))
    print('main sys.argv[0]:{}'.format(sys.argv[0]))
    print('main __file__:{}'.format(__file__))
 
    submodule.child_test()
if __name__ == '__main__':
    main()

目录结构

├── 01test
│   ├── 001_test      # 运行目录
│   └── mainmodule.py # 主模块
└── 02test 
    └── submodule.py  # 被调用模块

ok 来看看结果

Traceback (most recent call last):
  File "../mainmodule.py", line 3, in <module>
    import submodule
ModuleNotFoundError: No module named 'submodule'

我去,出现了点小状况

原因是系统找不到该模块的路径,我们来人工添加一个路径
在主模块中前面添加

sys.path.append(‘/Users/stephen/Documents/code/test_dir/02test/’)

再来试试 - -

结果如下:

main os.getcwd():/Users/stephen/Documents/code/test_dir/01test/001_test
main sys.path[0]:/Users/stephen/Documents/code/test_dir/01test
main sys.argv[0]:../mainmodule.py
main __file__:../mainmodule.py
sub os.getcwd():/Users/stephen/Documents/code/test_dir/01test/001_test
sub sys.path[0]:/Users/stephen/Documents/code/test_dir/01test
sub sys.argv[0]:../mainmodule.py
sub __file__:/Users/stephen/Documents/code/test_dir/02test/submodule.py

结合目录结构看就清楚了

├── 01test
│   ├── 001_test      # 运行目录
│   └── mainmodule.py # 主模块
└── 02test 
    └── submodule.py  # 被调用模块

os.getcwd() 指的是运行程序的目录 (绝对路径)
sys.path[0] 主要模块的目录 (绝对路径)
sys.argv[0] 运行模块时,pyhton 后面的参数
__file__ 这个就有点奇怪了,主模块显示的相对路径,而被调用模块却用的绝对路径

__file__ 还是有点疑虑,于是去 stack overflow(click to)看到了这句话,如下:

So, if you are outside the part of sys.path that contains the module, you'll get an absolute path. If you are inside the part of sys.path that contains the module, you'll get a relative path.
 
If you load a module in the current directory, and the current directory isn't in sys.path, you'll get an absolute path.
 
If you load a module in the current directory, and the current directory is in sys.path, you'll get a relative path.

意思大致是:

如果你(你所在的当前目录)不在sys.path的范围里,你会得到绝对路径,反之,你会得到相对路径

如果你在当前目录加载模块,并且当前目录在sys.path 里, 你会得到相对路径。
对比上面的结果,符合。

不过我们还是应该再来验证下。我们把当前路径换到子模块下

├── 01test
│   ├── 001_test     
│   └── mainmodule.py # 主模块
└── 02test            # 当前目录
    └── submodule.py  # 被调用模块

结果如下:

main os.getcwd():/Users/stephen/Documents/code/test_dir/02test
main sys.path[0]:/Users/stephen/Documents/code/test_dir/01test
main sys.argv[0]:../01test/mainmodule.py
main __file__:../01test/mainmodule.py
sub os.getcwd():/Users/stephen/Documents/code/test_dir/02test
sub sys.path[0]:/Users/stephen/Documents/code/test_dir/01test
sub sys.argv[0]:../01test/mainmodule.py
sub __file__:/Users/stephen/Documents/code/test_dir/02test/submodule.py

是不是觉得有问题?幸亏我们测试了

突然想起我我运行mainmodule用的相对路径
像这样:

$ python …/01test/mainmodule.py

然后__file__就是相对路径的,如果我们换成绝对路径呢?

$ python /Users/stephen/Documents/code/test_dir/01test/mainmodule.py

结果如下:

main os.getcwd():/Users/stephen/Documents/code/test_dir/02test
main sys.path[0]:/Users/stephen/Documents/code/test_dir/01test
main sys.argv[0]:/Users/stephen/Documents/code/test_dir/01test/mainmodule.py
main __file__:/Users/stephen/Documents/code/test_dir/01test/mainmodule.py
sub os.getcwd():/Users/stephen/Documents/code/test_dir/02test
sub sys.path[0]:/Users/stephen/Documents/code/test_dir/01test
sub sys.argv[0]:/Users/stephen/Documents/code/test_dir/01test/mainmodule.py
sub __file__:/Users/stephen/Documents/code/test_dir/02test/submodule.py

soga!
终于弄清楚了,突然有种小兴奋啊
总结一下:

    os.getcwd() 指的是当前目录,绝对路径
    sys.path[0] sys.path 指的是path,sys.path[0]为主模块目录的绝对路径,在模块运行的时候被自动添加进去
    sys.argv[0] 就是你运行时 python 后面跟的参数
    __file__ 表示所在模块文件的路径,和系统找到该模块的方式有关,你是用绝对路径去加载该模块,那么__file__就为绝对模块文件路径,如果你给系统提供相对路径去加载该模块,那么改文件路径为相对路径
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值