你還在用 os.path?快來感受一下 pathlib 給你帶來的便捷吧!

閱讀本文大概需要 5 分鐘。

概述

pathlib 是Python內置庫,Python 文檔給它的定義是 Object-oriented filesystem paths(面向對象的文件系統路徑)。pathlib 提供表示文件系統路徑的類,其語義適用於不同的操作系統。路徑類在純路徑之間劃分,純路徑提供純粹的計算操作而沒有I / O,以及具體路徑,它繼承純路徑但也提供I / O操作。

聽起來有點繞?那就對了,畢竟這是直譯過來的,但這並不影響我們喜愛它。 我們通過幾個例子來了解它吧

舉個栗子

相對於 os 模塊的 path 方法,Python3 標準庫 pathlib 模塊的 Path 對路徑的操作會更簡單。

獲取當前文件路徑

使用 os 模塊時,有兩種方法可以直接獲取當前文件路徑: import os value1 = os.path.dirname(__file__) value2 = os.getcwd() print(value1) print(value2)

pathlib 獲取當前文件路徑應該怎麼寫呢?

官方文檔給出了建議 插眼傳送

動手試一試

import pathlib

value1 = pathlib.Path.cwd()
print(value1)

它是如何實現的

文檔中有介紹,它以 os.getcwd() 的形式將路徑返回。我們去源碼中一探究竟(Pycharm 編輯器快捷鍵 ctrl+鼠標左鍵點擊即可跟進指定對象)

原來它是對 os 模塊中一些對象進行了封裝,看 cwd 的註釋: Return a new path pointing to the current working directory 意爲:返回指向當前工作目錄的新路徑。

看起來也沒什麼特別的,但是爲什麼官方特意將它推出呢?

其他的封裝

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 的構成,接下來讓我們感受一下它帶給我們的便捷。

獲取上層/上層目錄

也就是獲取它爺爺的名字

os 模塊的寫法爲:

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 的數量,來實現它祖輩的調節,美哉。

PurePath

上面的操作大部分都通過 pathlib 中的 Path 實現,其實它還有另一個模塊 PurePath。

PurePath 是一個純路徑對象,純路徑對象提供了實際上不訪問文件系統的路徑處理操作。有三種方法可以訪問這些類,我們也稱之爲flavor。

上面這句話來自於官方文檔,聽起來還是有點繞,我們還是通過栗子來了解它吧

PurePath.match

讓我們來判斷一下,當前文件路徑是否有符合 '*.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'))

打印通過 os.path 獲取當前路徑的結果,得出一個路徑字符串;而通過 pathlib.Pure 則獲得的是一個 PurePosixPath 對象,並且得到的路徑包括了當前文件 coder.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 應該有一個大體的瞭解,接下來再回顧一下官方給 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,你可以通過接口來實現你的目的(反之亦然)

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