pathlib模組
- 2019 年 10 月 3 日
- 筆記
一、pathlib庫官方定義
pathlib 是Python內置庫,Python 文檔給它的定義是 Object-oriented filesystem paths(面向對象的文件系統路徑)。pathlib 提供表示文件系統路徑的類,其語義適用於不同的作業系統。路徑類在純路徑之間劃分,純路徑提供純粹的計算操作而沒有 I / O,以及具體路徑,它繼承純路徑但也提供 I / O 操作。
對於這繁瑣而又冗餘的話,聽起來一定讓人不習慣。那就對了,因為這是使用Google翻譯直譯過來的,說到這我怎麼感覺我要回去偷偷補個英語,但是注意了,接下來大白話的語述並不影響你去了解並使用他。
二、os和pathlib.Path的區別
相對於 os 模組的 path 方法,Python3 標準庫 pathlib 模組的 Path 對路徑的操作會更簡單。
2.1 獲取當前文件路徑
使用 os 模組時,通過 getcwd()
方法可以直接獲取當前文件路徑(在 Pycharm 中,可以使用 os.path.dirname(__file__)
獲取當前文件路徑,因為 Python 並沒有提供 __file__ 這個概念,他是 Pycharm 提供的):
# python語言實現 # /Users/mac/test.py import os print(os.getcwd()) # '/Users/mac'
在 pathlib 模組中,通過 Path.cwd()
方法可以直接獲取當前文件路徑,我們可以動手試一試:
# python語言實現 # /Users/mac/test.py import pathlib print(pathlib.Path.cwd()) # PosixPath('/Users/mac')
通過 Pycharm 我們可以使用快捷鍵 ctrl+滑鼠左鍵
點擊查看該方法的詳細介紹,如下圖所示:
從上圖中可以看出 cwd()
方法不過是對 os 庫中 getcwd()
方法進行了封裝,看起來好像更差勁了,但是官方的推出一定不是子虛烏有的,現在讓我們一起來揭秘。
2.2 獲取上層/上層目錄
上面那個案例彷彿讓 pashlib 庫的使用變得更加複雜了,為了揭秘,我們只能一同感受下 pathlib 庫的構成,了解 pathlib 庫如何帶給我們便捷。
在 os 模組中,如果我們要獲取某一個文件的父目錄,os 模組的寫法為:
# python語言實現 # /Users/mac/test.py import os print(os.path.dirname(os.path.dirname(os.getcwd()))) # /Users
在 pathlib 庫中,可以通過這樣簡潔方法實現:
# python語言實現 # /Users/mac/test.py import pathlib print(pathlib.Path.cwd().parent) # /Users
這段程式碼看起來是不是更符合 Pythonic ?像寫英語一樣。不對,這個時候的我不應該在補英語嗎?/偷笑
並且,如果你需要找他爺爺,是不是再來一個 .parent
就行了。相比較 os 模組的 os.path.dirname()
是不是方便太多太多了?
2.3 路徑拼接
如果你要在他父目錄中拼接路徑,通過 os 模組你可能需要寫這麼一長串程式碼:
# python語言實現 # /Users/mac/test.py import os print(os.path.join(os.path.dirname(os.getcwd()), '路徑拼接', '真麻煩')) # /Users/路徑拼接/真麻煩
當你使用 pathlib 的時候,我們一起來感受他的便捷之處吧!
# python語言實現 # /Users/mac/test.py import os paths = ('路徑拼接', '真麻煩') print(pathlib.Path.cwd().parent.joinpath(*paths)) # /Users/路徑拼接/真麻煩
通過 pathlib 庫拼接路徑,你可以很方便的調節他在他祖輩的位置,妙哉。
2.4 其他封裝
pathlib 封裝了很多的 os.path
中的方法,如下所示:
# python語言實現 os.path.expanduser() --> pathlib.Path.home() os.path.expanduser() --> pathlib.Path.expanduser() os.stat() --> pathlib.Path.stat() os.chmod() --> pathlib.Path.chmod()
三、pathlib.PurePath的使用
上一節的操作大部分都是通過 pathlib 庫中的 Path 實現,其實他還有一個更加高大上的模組,也就是我們這一節的主角:pathlib.PurePath
。
PurePath 是一個純路徑對象,純路徑對象提供了實際上不訪問文件系統的路徑處理操作。有三種方法可以訪問這些類,我們也稱之為 flavor 。
上面這段話來自於官方文檔,感覺聽不懂也沒關係,下面我們將舉幾個栗子來剖析他。
3.1 PurePath.match
下面讓我們來實現一個神奇的功能,判斷下當前的路徑是否有符合’*.py’規則的文件。
# python語言實現 # /Users/mac/test.py import pathlib print(pathlib.PurePath(__file__).match('*.py')) # True
輸出為什麼會是 True
呢?因為當前文件夾下不就有一個 test.py
嗎?
3.2 PurePosixPath
看見 pathlib.PurePath 後面跟著 match,那是不是能說明他是個對象,而不是一個單純的路徑字元串,因此我們可以試著列印 pathlib.PurePath 看一看。
# python語言實現 # /Users/mac/test.py import pathlib os_path = os.path.dirname(__file__) print(os_path) # /Users/mac/ pure_path = pathlib.PurePath(__file__) print(pure_path) # /Users/mac/test.py <class 'pathlib.PurePosixPath'> print(pathlib.PurePath(__file__).match('*.py')) # True
通過列印 os.path 獲取當前路徑的結果,得到一個路徑字元串;而通過 pathlib.PurePath 則獲得了一個 PurePosixPath 對象,並且由此得到的路徑包括了當前文件 test.py。
那麼問題來了,PurePosixPath究竟是什麼玩意呢?能不能像機器貓的記憶麵包一樣幫助我速成英語。下面不得不又一次展示我們這個官方文檔了:
pathlib 可以操作兩種文件系統的路徑,一種是 Windows 文件系統,另一種稱為非 Windows 文件系統,對應的對象是 pathlib.PurePosixPath 和 pathlib.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和pathlib的對應關係
少俠,上幾節中老夫已經將畢生所學教給你了,未來只能靠你自己去參考這份武林秘籍——九陰真經,他詳盡的描述了 os 模組和 pathlib 庫的對應關係,如果忘了,別忘了多回家看看。
五、pathlib秘籍
5.1 基本用法
# python語言實現 Path.iterdir() # 遍歷目錄的子目錄或者文件 Path.is_dir() # 判斷是否是目錄 Path.glob() # 過濾目錄(返回生成器) Path.resolve() # 返回絕對路徑 Path.exists() # 判斷路徑是否存在 Path.open() # 打開文件(支援with) Path.unlink() # 刪除文件或目錄(目錄非空觸發異常)
5.2 基本屬性
# python語言實現 Path.parts # 分割路徑 類似os.path.split(), 不過返回元組 Path.drive # 返回驅動器名稱 Path.root # 返迴路徑的根目錄 Path.anchor # 自動判斷返回drive或root Path.parents # 返回所有上級目錄的列表
5.3 改變路徑
# python語言實現 Path.with_name() # 更改路徑名稱, 更改最後一級路徑名 Path.with_suffix() # 更改路徑後綴
5.4 拼接路徑
# python語言實現 Path.joinpath() # 拼接路徑 Path.relative_to() # 計算相對路徑
5.5 測試路徑
# python語言實現 Path.match() # 測試路徑是否符合pattern Path.is_dir() # 是否是文件 Path.is_absolute() # 是否是絕對路徑 Path.is_reserved() # 是否是預留路徑 Path.exists() # 判斷路徑是否真實存在
5.6 其他方法
# python語言實現 Path.cwd() # 返回當前目錄的路徑對象 Path.home() # 返回當前用戶的home路徑對象 Path.stat() # 返迴路徑資訊, 同os.stat() Path.chmod() # 更改路徑許可權, 類似os.chmod() Path.expanduser() # 展開~返回完整路徑對象 Path.mkdir() # 創建目錄 Path.rename() # 重命名路徑 Path.rglob() # 遞歸遍歷所有子目錄的文件
六、pathlib回顧
通過上面的幾個例子,我們對 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操作。
回顧上一章清明上河圖:
如果你以前從未使用過這個模組,或者只是不確定哪個類適合您的任務,那麼 Path 很可能就是您所需要的。他會為程式碼運行的不同的系統實例化屬於該系統的具體路徑,而不需要你自己設定。
七、總結
pathlib 不是單純的對 os 中的一些方法進行封裝,而是為了兼容不同的作業系統而生。他為每類作業系統定義了介面,也就是說你希望在UNIX系統上操作Windows系統的路徑,直接操作是不可能的,所以他為你創建了一套介面 PurePath,你可以通過介面來實現你的目的(反之亦然)。