top of page
Search
  • Learn with Shin

路徑小幫手 - pathlib

Updated: Jul 28, 2021



人生好難,要怎麼樣才能找到正確的路徑...😔



咳咳 ~今天不是要討論這麼沈重的話題啦 😅


是說,在寫Python的時候,有時候會需要讀取(或寫入)檔案吧?


譬如說,我有一個文字檔案,想要讀到 我的Python 程式裡面。這時我們需要提供該檔案的路徑,像這樣👇:


Python就可以根據你提供的路徑找到你要的檔案 。


那麼,這個路徑還有什麼特色呢?這個今天我們就來看一下Python路徑的眉眉角角 😀。



路徑(Path)


首先稍微談一下這個所謂的檔案路徑吧。



根據你的電腦的作業系統(Operating System),路徑的長相會不一樣。


Windows系統的Path長得像這樣:

C:\user\docs\my_file.txt


Mac或Linux系統的Path長得像這樣:

/home/user/docs/my_file.txt


有注意到分隔的斜線是相反的🧐?


如果你是使用Windows的話,其實在Python中當我們提供路徑的時候,是可以把斜線反過來的。所以下面這樣的路徑是OK的:


with open("C:/user/docs/my_file.txt") as f:
    ...

不然的話,你可能得用像這樣的寫法(加一個r 在string之前)來提供原始字串(raw string literals):


with open(r"C:\user\docs\myFile.txt") as f:
    ...

因為這個反斜線(blackslash)在一些程式語言包括Python,代表的是一個Escape Character,基本上有它特殊的意義及作用,今天先不多做敘述。



絕對路徑 & 相對路徑


再來,當我們在提供路徑時,基本上有兩種選項:

  • 絕對路徑(Absolute Path)

  • 相對路徑(Relative Path)


絕對路徑就是你的檔案的完整路徑(Full Path),像我們上面看到的Mac的路徑:

/home/user/docs/my_file.txt

清楚易懂,對吧?



至於相對路徑就稍微有一點麻煩了 🤨。


它是根據你目前執行指令的資料夾地點(Current Working Directory),與所指定的File的相對位置。


Say what???


舉個例子來看,假設下面是你的資料夾構造(Folder Structure):


/directory_1
  /directory_2
    + my_program.py
    + my_program_2.py
    + my_file.txt

假設我在my_program.py裡面有這一段code:


然後你在directory_2這個folder底下執行:


$cd directory_2
$python my_program.py

嗯,這樣應該是不會有任何問題。Everything works!


這裡我給的路徑 "my_file.txt",就是一個相對路徑。Python會自動去試著辨別你給的路徑是絕對路徑或相對路徑。


相對於我執行的位置(directory_2),我可以在同一個資料夾中找到myFile.txt。(你也可以寫作 "./my_file.txt" ,這個小點點(.)指的就是現在所在的資料夾)


可是瑞凡...今天如果你跑到directory_1,然侯去執行my_program.py的話...



$cd ..  # go up one directory to directory_1
$python directory_2/my_program.py 


Oh no~ 你會得到一個像這樣的Error:

FileNotFoundError: [Errno 2] No such file or directory: 'my_file.txt'


因為相對於你當前的位置(directory_1),my_file.txt並不存在。


我們為了方便(或只是懶惰)常常會使用相對路徑。那麼,該如何才能更有彈性的從任何地方都可以執行你的程式,不受限於你的Current Working Directory呢?


我們稍後會再回來看這一點。


OK,說了那麼多,今天主要想跟大家一起來看一下Python內建的pathlib模組(注意這是python 3.4 版本之後才有的喔),來幫我們更俐落的處理路徑問題!



路徑物件


以往我們看到路徑的表現方式是用單純的string(像是"/home/user/docs/myFile.txt")。


pathlib則是將路徑以物件的方式呈現(簡單來說就是一個叫做路徑的特殊資料類型)。透過這個路徑物件,我們能更輕鬆直覺的做各種路徑的操作~🙂


來看以下的例子(假設我們在directory_2下執行my_program.py):


Path.cwd( ) 會產生一個路徑物件來代表Current Working Directory。

你可以利用這個路徑物件在你的File System中遊走,並生成新的路徑物件。

  • 如果要往上一個directory,利用 .parent這個屬性;

  • 如果要往下,利用 "/" 這個符號加上你的資料夾或檔案的名字。


承接上面的例子:


話說,當我們用print來顯示物件的時候,印出來的是物件的string的表示方式(String Representation),看起來就像是一般的文字路徑。但是不要忘了,他可還是一個路徑物件。


利用這個路徑物件,我們還可以直接讀取檔案內容喔:


這邊用到的是.read_text這個method,看起來是不是相當清爽~😃



接下來再介紹一個很有用的功能:


有時候,我們會需要在一個資料夾裡面做檔案的搜尋,譬如說:找出所有的csv檔案。


利用路徑物件的.glob功能,我們可以快速的做到這一件事,不需要自己寫for loop喔。



.glob("*.csv") 會找出所有結尾為 .csv的檔案,而且每一個檔案都已經是路徑物件了喔 😀。意思就是,你可以取出當中的任何一個檔案,然後直接用.read_text。


注意這裡glob會給我們一個generator,因此我們用list功能把它做個轉換成實體的List。



路徑轉換


接下來看一下先前提到的,如何更有彈性的利用相對路徑讓你可以從任何地方來執行程式。


我們可以利用__file__這一個內建的variable來做到這一點。__file__會根據你當下執行的地點(current working directory),給我們檔案(這裡指的是my_program_2.py)相對的位置 。


this_file_path.parent指的是my_program_2.py存在的資料夾(也就是directory_2)。因為我們知道,my_file.txt跟my_program_2.py是在同一個資料夾內。


這樣一來,不論你是在directory_2下面,


$cd directory_2  
$python my_program_2.py

或是回到directory_1來執行,


$cd ..  # go up one directory to directory_1
$python directory_2/my_program_2.py 

都不會有任何問題👍🏻!


另外,如果你想要拿到絕對路徑的String的話,你可以利用 .resolve這個method。




結論


今天我們針對Python的路徑跟大家簡單做了以下的介紹:

  • 何謂路徑

  • 絕對路徑以及相對路徑的概念

  • pathlib的路徑物件

  • 如何提供有彈性的路徑

Python的pathlib還有許多其他的功能,包括做檔案的移動、拷貝或刪除、以及許多的小幫手功能像是檢驗路徑是否存在,是否為檔案或是文件夾,還有檔名的擷取等等...詳細的官方介紹可以參考這裡


善用pathlib,幫助我們寫出更易讀且符合現代Python標準(pythonic)的Code喔 ~😉





Comments


Post: Blog2_Post
bottom of page