python進階14文件路徑(找不到文件)

原創鏈接:python進階14文件路徑(找不到文件)

開發時遇到問題,文件路徑不正確,找不到文件等等,都是這一類問題.

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章