sys.path 与 os.getcwd区分:代码运行中的路径问题
获取当前工作目录import sys print(sys.path[0])获取执行命令的位置import os print(os.getcwd())python 代码运行路径问题在下载使用别人的代码进行运行时有时会遇到路径问题。将自己目前遇到的进行分类和总结。主要分为两类import相关 open文件相关问题的来源是IDE和cmd的默认工作路径的差异或模块搜索路径不同。即可能是自己和对方使用的IDE的不同默认工作路径导致的。当前工作目录文件读写等相关操作使用的基本路径。通过函数os.getcwd()获得通过函数os.chdir()改变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_testok 现在编写两模块代码子模块 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, youll get an absolute path. If you are inside the part of sys.path that contains the module, youll get a relative path. If you load a module in the current directory, and the current directory isnt in sys.path, youll get an absolute path. If you load a module in the current directory, and the current directory is in sys.path, youll 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.pysoga!终于弄清楚了突然有种小兴奋啊总结一下os.getcwd() 指的是当前目录绝对路径 sys.path[0] sys.path 指的是pathsys.path[0]为主模块目录的绝对路径在模块运行的时候被自动添加进去 sys.argv[0] 就是你运行时 python 后面跟的参数 __file__ 表示所在模块文件的路径和系统找到该模块的方式有关你是用绝对路径去加载该模块那么__file__就为绝对模块文件路径如果你给系统提供相对路径去加载该模块那么改文件路径为相对路径案例demo自己的工程代码修改了自己的代码然后单卡上能跑到自己修改的代码但是多卡训练的时候就跑不到自己修改的代码像是跑到了pip安装的库。原因是需要加上下面的代码注一在终端或者~/.bashrc里直接添加PYTHONPATH/data/perception/bev/adb/adb_code/ADB_DLA:$PYTHONPATH不管用_p os.environ.get(“PYTHONPATH”, “”)os.environ[“PYTHONPATH”] “/data/perception/bev/adb/adb_code/ADB” (os.pathsep _p if _p else “”)importos os.chdir(os.path.dirname(__file__))importsys sys.path.insert(0,/data/perception/bev/adb/adb_code/ADB)# 多卡 DDP 子进程由 torchrun 拉起需能 import 本地 ultralytics非 pip 安装通过 PYTHONPATH 传递_pos.environ.get(PYTHONPATH,)os.environ[PYTHONPATH]/data/perception/bev/adb/adb_code/ADB(os.pathsep_pif_pelse)