相比經常使用的 os.path而言,pathlib 對於目錄路徑的操做更簡介也更貼近 Pythonic。可是它不單純是爲了簡化操做,還有更大的用途html
pathlib 是Python內置庫,Python 文檔給它的定義是 Object-oriented filesystem paths(面向對象的文件系統路徑)。pathlib 提供表示文件系統路徑的類,其語義適用於不一樣的操做系統。路徑類在純路徑之間劃分,純路徑提供純粹的計算操做而沒有I / O,以及具體路徑,它繼承純路徑但也提供I / O操做。python
聽起來有點繞?那就對了,畢竟這是直譯過來的,但這並不影響咱們喜好它。 咱們經過幾個例子來了解它吧bash
相對於 os 模塊的 path 方法,Python3 標準庫 pathlib 模塊的 Path 對路徑的操做會更簡單。微信
使用 os 模塊時,有兩種方法能夠直接獲取當前文件路徑:app
import os
value1 = os.path.dirname(__file__)
value2 = os.getcwd()
print(value1)
print(value2)
複製代碼
pathlib 獲取當前文件路徑應該怎麼寫呢?編輯器
官方文檔給出了建議 插眼傳送ide
動手試一試測試
import pathlib
value1 = pathlib.Path.cwd()
print(value1)
複製代碼
文檔中有介紹,它以 os.getcwd() 的形式將路徑返回。咱們去源碼中一探究竟(Pycharm 編輯器快捷鍵 ctrl+鼠標左鍵點擊便可跟進指定對象)ui
原來它是對 os 模塊中一些對象進行了封裝,看 cwd 的註釋: Return a new path pointing to the current working directory
意爲:返回指向當前工做目錄的新路徑。this
看起來也沒什麼特別的,可是爲何官方特地將它推出呢?
pathlib 封裝了不少的 os path ,文檔中有寫明,如:
# 關係說明
os.path.expanduser() --> pathlib.Path.home()
os.path.expanduser() --> pathlib.Path.expanduser()
os.stat() --> pathlib.Path.stat()
os.chmod() --> pathlib.Path.chmod()
複製代碼
官網文檔截圖:
詳細請查看官方文檔:插眼傳送
剛纔的案例並不能說明什麼,只是讓咱們瞭解到 pathlib 的構成,接下來讓咱們感覺一下它帶給咱們的便捷。
也就是獲取它爺爺的名字
import os
print(os.path.dirname(os.path.dirname(os.getcwd())))
複製代碼
若是用 pathlib 來實現:
import pathlib
print(pathlib.Path.cwd().parent.parent)
複製代碼
parent 就完事了,這是否是更貼近 Pythonic ? 像寫英語同樣寫代碼。
若是你只須要找到它爸爸,那就使用一次:
import pathlib
print(pathlib.Path.cwd().parent)
複製代碼
你還能夠繼續往祖輩上找:
import pathlib
print(pathlib.Path.cwd().parent.parent.parent)
複製代碼
相對與以前 os 模塊使用的多層 os.path.dirname,使用 parent 是否是便捷不少?
若是你要在它爺爺輩那裏拼接路徑,那麼你須要寫這麼長一串代碼:
import os
print(os.path.join(os.path.dirname(os.path.dirname(os.getcwd())), "關注", "微信公衆號", "【進擊的", "Coder】"))
複製代碼
當你用 pathlib 的時候,你必定可以感覺到快樂:
import pathlib
parts = ["關注", "微信公衆號", "【進擊的", "Coder】"]
print(pathlib.Path.cwd().parent.parent.joinpath(*parts))
複製代碼
並且你還能夠經過增長或減小 parent 的數量,來實現它祖輩的調節,美哉。
上面的操做大部分都經過 pathlib 中的 Path 實現,其實它還有另外一個模塊 PurePath。
PurePath 是一個純路徑對象,純路徑對象提供了實際上不訪問文件系統的路徑處理操做。有三種方法能夠訪問這些類,咱們也稱之爲flavor。
上面這句話來自於官方文檔,聽起來仍是有點繞,咱們仍是經過栗子來了解它吧
讓咱們來判斷一下,當前文件路徑是否有符合 '*.py' 規則的文件
import pathlib
print(pathlib.PurePath(__file__).match('*.py'))
複製代碼
很顯然,咱們編寫代碼的 coder.py 就符合規則,因此輸出是 True。
爲何我要拿這個來舉例呢?再深刻想一下 pathlib.PurePath 後面可以跟着 match,那說明它應該是個對象,而不是一個路徑字符串。爲了驗證這個想法,把代碼改一改:
import pathlib
import os
os_path = os.path.dirname(__file__)
pure_path = pathlib.PurePath(__file__)
print(os_path, type(os_path))
print(pure_path, type(pure_path))
print(pathlib.PurePath(__file__).match('*.py'))
複製代碼
這就有點懸疑了, PurePosixPath 到底是什麼?
pathlib 能夠操做兩種文件系統的路徑,一種是 Windows 文件系統,另外一種稱爲非 Windows 文件系統,對應的對象是 pathlib.PurePosixPath 和 PureWindowsPath,不過不用擔憂,這些類並不是是指定在某些操做系統上運行纔可以使用,不管你運行的是哪一個系統,均可以實例化全部這些類,由於它們不提供任何進行系統調用的操做。
不提供任何進行系統調用的操做,這又是什麼?真是越聽越深了
文檔在最開始給出了這麼一段描述:
Pure paths are useful in some special cases; for example: If you want to manipulate Windows paths on a Unix machine (or vice versa). You cannot instantiate a WindowsPath when running on Unix, but you can instantiate PureWindowsPath. You want to make sure that your code only manipulates paths without actually accessing the OS. In this case, instantiating one of the pure classes may be useful since those simply don’t have any OS-accessing operations.
翻譯:純路徑在某些特殊狀況下頗有用; 例如: 若是要在Unix計算機上操做Windows路徑(反之亦然)。WindowsPath在Unix上運行時沒法實例化,但能夠實例化PureWindowsPath。 您但願確保您的代碼僅操做路徑而不實際訪問操做系統。在這種狀況下,實例化其中一個純類可能頗有用,由於那些只是沒有任何操做系統訪問操做。
還附上了一張圖:
一會兒也不是很理解,這是什麼意思。沒關係,繼續往下看。
經過以上的例子咱們能夠感覺到,它不只封裝了 os.path 相關經常使用方法,還集成了 os 的其餘模塊,好比建立文件夾 Path.mkdir。
若是你擔憂記不住,不要緊的,文檔一直都在。而且文檔給咱們列出了對應關係表
Path.iterdir() # 遍歷目錄的子目錄或者文件
Path.is_dir() # 判斷是不是目錄
Path.glob() # 過濾目錄(返回生成器)
Path.resolve() # 返回絕對路徑
Path.exists() # 判斷路徑是否存在
Path.open() # 打開文件(支持with)
Path.unlink() # 刪除文件或目錄(目錄非空觸發異常)
Path.parts # 分割路徑 相似os.path.split(), 不過返回元組
Path.drive # 返回驅動器名稱
Path.root # 返回路徑的根目錄
Path.anchor # 自動判斷返回drive或root
Path.parents # 返回全部上級目錄的列表
Path.with_name() # 更改路徑名稱, 更改最後一級路徑名
Path.with_suffix() # 更改路徑後綴
Path.joinpath() # 拼接路徑
Path.relative_to() # 計算相對路徑
Path.match() # 測試路徑是否符合pattern
Path.is_dir() # 是不是文件
Path.is_absolute() # 是不是絕對路徑
Path.is_reserved() # 是不是預留路徑
Path.exists() # 判斷路徑是否真實存在
Path.cwd() # 返回當前目錄的路徑對象
Path.home() # 返回當前用戶的home路徑對象
Path.stat() # 返回路徑信息, 同os.stat()
Path.chmod() # 更改路徑權限, 相似os.chmod()
Path.expanduser() # 展開~返回完整路徑對象
Path.mkdir() # 建立目錄
Path.rename() # 重命名路徑
Path.rglob() # 遞歸遍歷全部子目錄的文件
經過上面的幾個例子,咱們對 pathlib 應該有一個大致的瞭解,接下來再回顧一下官方給 pathlib 庫的定義:
This module offers classes representing filesystem paths with semantics appropriate for different operating systems. Path classes are divided between pure paths, which provide purely computational operations without I/O, and concrete paths, which inherit from pure paths but also provide I/O operations.
釋義:pathlib 提供表示文件系統路徑的類,其語義適用於不一樣的操做系統。路徑類在純路徑之間劃分,純路徑提供純粹的計算操做而沒有I / O,以及具體路徑,它繼承純路徑但也提供I / O操做。
回顧剛纔這張圖,從新理解 pathlib
若是你之前從未使用過這個模塊,或者只是不肯定哪一個類適合您的任務,那麼Path極可能就是您所須要的。它爲代碼運行的平臺實例化一個具體路徑。
總結:pathlib 不單純是對 os 中一些模塊或方法進行封裝,而是爲了兼容不一樣的操做系統,它爲每類操做系統定義了接口。你但願在UNIX機器上操做Windows的路徑,然而直接操做是作不到的,因此爲你建立了一套接口 PurePath,你能夠經過接口來實現你的目的(反之亦然)