Python 好用模組 - pathlib
Posted on Oct 19, 2020 in Python 程式設計 - 初階 by Amo Chen ‐ 3 min read
Python 的 os 模組提供不少便利的功能讓我們能夠操作檔案/資料夾的路徑、操作等等。直到 Python 3.4 之後提供一個新模組 pathlib,將各種檔案/資料夾相關的操作封裝在 Path 等類別之中,讓檔案/資料夾的操作更加物件導向。
本文將說明與展示 pathlib 模組。
本文環境
- Python 3.6.5
- macOS 10.15
Path 類別
pathlib 底下有許多類別可供使用,例如 WindowsPath , PosixPath , PurePath 等等。一般來說,只要使用 Path 類別即可,不需要特意按照不同平台使用不同的類別。
接下來,實際以多個範例介紹如何使用 Path 類別!
檢查檔案或資料夾是否存在
以往檢查檔案是否存在,會用類似以下的程式碼進行檢查:
>>> import os
>>> os.path.exists('/tmp/myfile.txt')
如果改成 Path 類別後,就是以下形式:
>>> from pathlib import Path
>>> path = Path('/tmp/myfile.txt')
>>> path.exists()
False
上述範例可以看到透過 Path 類別所提供的 exists()
方法即可判斷檔案是否存在。整體而言,程式碼閱讀起來也更為簡潔易懂,更加物件導向。
建立檔案
用過 Linux 的人可能都會知道能夠用 touch
指令建立檔案,而 Path 也提供一樣的功能:
>>> from pathlib import Path
>>> path = Path('/tmp', 'myfile.txt')
>>> path.exists()
False
>>> path.touch()
>>> path.exists()
True
上述範例可以看到執行 path.touch()
之後,檔案就被建立起來。
取得檔名 / 副檔名
以往取得檔名、副檔名可以透過 os.path.basename() 與 os.path.splitext() 達成。而 Path 提供 name
與 suffix
屬性能夠輕鬆取得檔名與副檔名:
>>> from pathlib import Path
>>> path = Path('/tmp', 'myfile.txt')
>>> path.name
myfile.txt
>>>
>>> path.suffix
.txt
寫入 / 讀取檔案
Path 類別也提供 write_text() , read_text() 等方法,讓開發者可以輕鬆地寫入、讀取檔案:
>>> from pathlib import Path
>>> path = Path('/tmp', 'myfile.txt')
>>> path.write_text('Hello')
5
>>> path.write_text('World')
5
值得注意的是,上述範例執行 2 次 write_text()
,檔案內容並不會附加,而是直接覆寫(overwrite) ,因此以下 read_text()
只會讀取到 World:
>>> path.read_text()
'World'
此外, Path 也有支援 with 語法以及 open() 方法:
>>> with path.open('w') as f:
... f.write('Hello')
5
is_file / is_dir / is_symlink
以往判斷路徑是否為檔案、資料夾、 symbol link 會使用以下程式碼進行判斷:
>>> import os
>>> os.path.isfile('/tmp/myfile.txt')
>>> os.path.isdir('/tmp/myfile.txt')
>>> os.path.islink('/tmp/myfile.txt')
這些常用的方法也被整合至 Path 中:
>>> from pathlib import Path
>>> path = Path('/tmp', 'myfile.txt')
>>> path.touch()
>>> path.is_file()
True
>>> path.is_dir()
False
>>> path.is_symlink()
False
當然,其他還有 is_socket() is_fifo() is_block_device() 等更多方法可以使用。
刪除檔案
正因為 Path 類別整合各種與檔案、資料夾相關的操作,理想當然也能夠呼叫刪除檔案的方法:
>>> from pathlib import Path
>>> path = Path('/tmp', 'myfile.txt')
>>> path.touch()
>>> path.is_file()
True
>>> path.unlink()
>>> path.exists()
False
上述範例在呼叫 unlink() 方法後,檔案就被刪除了。
取得檔案大小
Path 類別也提供 stat() 方法讓開發者可以取得檔案詳細的資訊,例如經常會使用的檔案大小。
我們可以先用以下程式碼建立一個很小的檔案:
>>> from pathlib import Path
>>> path = Path('/tmp', 'myfile.txt')
>>> path.touch()
>>> path.write_text('HelloWorld')
10
接著呼叫 stat()
方法,可以看到 stat()
方法會回傳 os.stat_result ,其中 st_size
就是我們需要的檔案大小:
>>> path.stat()
os.stat_result(st_mode=33188, st_ino=20705682, st_dev=16777224, st_nlink=1, st_uid=501, st_gid=0, st_size=10, st_atime=1602572294, st_mtime=1602572354, st_ctime=1602572354)
因此可以用 path.stat().st_size
直接取得檔案大小 10 bytes:
>>> path.stat().st_size
10
走訪資料夾內的所有檔案與資料夾
另一個經常會用到的需求就是走訪某資料夾內的所有檔案與資料夾,只要呼叫 iterdir() 即可:
>>> from pathlib import Path
>>> for x in Path('/tmp').iterdir():
... print(type(x), x)
...
<class 'pathlib.PosixPath'> /tmp/com.google...
<class 'pathlib.PosixPath'> /tmp/com.apple...
<class 'pathlib.PosixPath'> /tmp/myfile.txt
<class 'pathlib.PosixPath'> /tmp/...
上述範例值得注意的是 iterdir()
所 yield 的每 1 個元素也是 Parh 類別的實例,因此同樣能夠享用 Path 類別所提供的各種便利功能。
Path 的運算
Path 類別還有 1 個有趣的特性,該類別實例(instance)能夠透過 /
除法運算元進行路徑的合併,例如:
>>> Path('/home') / Path('abc')
PosixPath('/home/abc')
此外也可以 2 個 Path 類別實例之間進行比較:
>>> Path('/tmp') == Path('/tmp')
True
>>> Path('/tmp/a') == Path('/tmp/b')
False
總結
除了前述所提及的功能與範例之外, Path 類別其實還有相當多的便利功能可以使用,有興趣的話,不妨閱讀官方文件。
另外,官方文件也整理出對照 Path
與 os
模組相關功能的對照表,可以參考 Correspondence to tools in the os module 一表。
References
https://docs.python.org/3/library/pathlib.html