開發時遇到問題,文件路徑不正確,找不到文件等等,都是這一類問題.
curdir,argv,file
文件1代碼:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
def get_cur_path1(): import os print(os.path.abspath(os.curdir)) def get_cur_path2(): import sys print(sys.argv[0]) def get_cur_path3(): import os print(os.path.abspath(__file__)) |
文件2代碼:
1 2 3 4 5 |
from test.testSub01.getFilePath import get_cur_path3, get_cur_path2, get_cur_path1 get_cur_path1() get_cur_path2() get_cur_path3() |
文件2執行輸出結果和解析:
1 2 3 |
/home/john/PYTHON/DjangoZero/test #01,項目work dir /home/john/PYTHON/DjangoZero/test/testFilePath.py #02,調用者的路徑 /home/john/PYTHON/DjangoZero/test/testSub01/getFilePath.py #03,當前文件真實路徑 |
如果在代碼01,裏面寫了open(‘../a/‘,’r’)類似的代碼,那麼其實是使用了workdir爲基準的路徑,
本例就是:/home/john/PYTHON/DjangoZero/test/../a=>/home/john/PYTHON/DjangoZero/a/
如果大家都是同一個項目,一般沒問題,有偶爾會有別人開發的模塊,自己去調用,發現別人可以正常跑的代碼,自己確提示找不到文件
大概率就是workdir配置的不一致導致,(默認work direction,大部分是執行的py文件的父文件夾,比如aa/bb/c.py 就是aa/bb/)
如何解決此類問題呢?最好的做法是使用上面“03,當前文件真實路徑爲基準”的方法(以03返回的路徑爲基準,../到需訪問文件相應的文件夾),這樣的話,不論從哪裏調用,只要py和要訪問的目標文件相對位置不變就行了,而覺大多數情況下,二者是位於同一個文件夾中的。
舉例:如果在getFilePath.py中訪問,上層文件夾同級別的README.md,則使用
1 2 |
with open(os.path.join(os.path.dirname(__file__),'../README.md')) as f: print(f.read()) |
這樣的話,不論從哪個路調用getFilePath.py裏面的方法,都會找到文件的正確路徑。
normpath
另外在做路徑連接時,優先使用os.path.normpath,而非os.path.join,雖然join比較常見,但是坑比較多
1 2 3 4 5 6 7 8 9 10 11 12 |
print('normpath') print(os.path.normpath("%s/%s" % ("dirName1", "dirName2"))) print(os.path.normpath("%s/%s" % ("/dirName1", "dirName2"))) print(os.path.normpath("%s/%s" % ("/dirName1/", "dirName2"))) print(os.path.normpath("%s/%s" % ("/dirName1/", "/dirName2"))) print(os.path.normpath("%s/%s" % ("/dirName1/", "/dirName2/"))) print(os.path.normpath("%s/%s" % ("/dirName1/", "/dirName2/1.txt"))) print('join') print(os.path.join("dirName1", "dirName2")) print(os.path.join("/dirName1/", "/dirName2")) print(os.path.join("/dirName1/", "/dirName2/")) print(os.path.join("dirName1", "dirName2/1.txt")) |
運行結果:
1 2 3 4 5 6 7 8 9 10 11 12 |
normpath# 結果均符合直觀理解 dirName1/dirName2 /dirName1/dirName2 /dirName1/dirName2 /dirName1/dirName2 /dirName1/dirName2 /dirName1/dirName2/1.txt join# 個別結果不符合直觀理解 dirName1/dirName2#符合直觀 /dirName2#不符合直觀 /dirName2/#不符合直觀 dirName1/dirName2/1.txt#符合直觀 |
更多功能測試
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
(base) john@john-P95-HP:~/PYTHON/DjangoZero$ python test/testFilePath.py argv:test/testFilePath.py file:test/testFilePath.py abs file:/home/john/PYTHON/DjangoZero/test/testFilePath.py dir file:test dir abs file :/home/john/PYTHON/DjangoZero/test curdir:. abs file:/home/john/PYTHON/DjangoZero dir file: dir abs file :/home/john/PYTHON getpwd:/home/john/PYTHON/DjangoZero abs file:/home/john/PYTHON/DjangoZero dir file: dir abs file :/home/john/PYTHON cur:. abs cur:/home/john/PYTHON/DjangoZero argv:['test/testFilePath.py'] file:/home/john/PYTHON/DjangoZero/test/testSub01/getFilePath.py abs file:/home/john/PYTHON/DjangoZero/test/testSub01/getFilePath.py |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
(base) john@john-P95-HP:~/PYTHON/DjangoZero$ cd test/ (base) john@john-P95-HP:~/PYTHON/DjangoZero/test$ python testFilePath.py argv:testFilePath.py file:testFilePath.py abs file:/home/john/PYTHON/DjangoZero/test/testFilePath.py dir file: dir abs file :/home/john/PYTHON/DjangoZero/test curdir:. abs file:/home/john/PYTHON/DjangoZero/test dir file: dir abs file :/home/john/PYTHON/DjangoZero getpwd:/home/john/PYTHON/DjangoZero/test abs file:/home/john/PYTHON/DjangoZero/test dir file: dir abs file :/home/john/PYTHON/DjangoZero cur:. abs cur:/home/john/PYTHON/DjangoZero/test argv:['testFilePath.py'] file:/home/john/PYTHON/DjangoZero/test/testSub01/getFilePath.py abs file:/home/john/PYTHON/DjangoZero/test/testSub01/getFilePath.py |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
(base) john@john-P95-HP:~/PYTHON/DjangoZero/test$ /home/john/anaconda3/envs/django_zero/bin/python testFilePath.py argv:testFilePath.py file:testFilePath.py abs file:/home/john/PYTHON/DjangoZero/test/testFilePath.py dir file: dir abs file :/home/john/PYTHON/DjangoZero/test curdir:. abs file:/home/john/PYTHON/DjangoZero/test dir file: dir abs file :/home/john/PYTHON/DjangoZero getpwd:/home/john/PYTHON/DjangoZero/test abs file:/home/john/PYTHON/DjangoZero/test dir file: dir abs file :/home/john/PYTHON/DjangoZero cur:. abs cur:/home/john/PYTHON/DjangoZero/test argv:['testFilePath.py'] file:/home/john/PYTHON/DjangoZero/test/testSub01/getFilePath.py abs file:/home/john/PYTHON/DjangoZero/test/testSub01/getFilePath.py |
父文件路徑
argv=FILE
abs(),dir()函數,
cur()簡寫.
getpwd(),cur()表現一致
子文件路徑
argv!=file
agrv:啓動腳本的argv(父程序)
File:子程序完整路徑
abs(cur):父程序啓動位置路徑
getcwd和abs(cur)依然一致
使用 file 獲取當前路徑:file 表示顯示文件當前的位置:
如果當前文件包含在 sys.path 裏面,那麼 file 返回一個相對路徑
如果當前文件不包含在 sys.path 裏面,那麼 file 返回一個絕對路徑
os.getcwd()與os.curdir的使用
os.getcwd()與os.curdir都是用於獲取當前執行python文件的文件夾,不過當直接使用os.curdir時會返回‘.’(這個表示當前路徑),記住返回的是當前執行python文件的文件夾,而不是python文件所在的文件夾。
PS:os.getcwd()與os.path.abspath(os.curdir)返回的結果是一樣的.
附錄
Python - 編寫模塊時 獲取當前路徑 file 與 getcwd():https://blog.csdn.net/sigmarising/article/details/83444463
python函數深入淺出 12.os.getcwd()函數詳解:https://www.jianshu.com/p/77bf050ba274