相信現(xiàn)在依然有很多人習慣于使用os
來處理文件/文件夾/路徑等,但其實Python/ target=_blank class=infotextkey>Python自帶的Pathlib
庫處理這些更優(yōu)雅、更安全,你會發(fā)現(xiàn)很多大型開源項目都在使用它,那么它到底有什么魅力?花點時間讓我們一起看看吧
先看這個引例,假設我們需要獲取某個文件夾下所有的txt文件,基于os
會寫成如下形式
import os
dir_path = "/home/user/documents"# Find all text files inside a directory
files = [os.path.join(dir_path, f) for f in os.listdir(dir_path) if os.path.isfile(os.path.join(dir_path, f)) and f.endswith(".txt")]
使用Pathlib
則變成如下形式,是不是心動了
from pathlib import Path
dir_path = Path("/home/user/documents")
files = list(dir_path.glob("*.txt"))
os.path
的最大缺點是將系統(tǒng)路徑視為字符串,極容易導致混亂,Pathlib
在Python3.4中被支持, 通過將路徑表示為獨特的對象解決了這個問題,并為路徑處理引入更多可擴展用法,許多操作在os
需要層層嵌套,而Pathlib
將使開發(fā)人員更輕松地處理與路徑和文件相關(guān)的所有事情
處理路徑
1. 創(chuàng)建路徑
幾乎所有pathlib
的功能都可以通過其 Path
子類訪問,可以使用該類創(chuàng)建文件和目錄
有多種初始化Path
的方式,比如,使用當前工作路徑
from pathlib import Path
Path.cwd() # PosixPath('/home/user/Downloads')
使用home
Path.home() # PosixPath('/home/user')
同樣的可以指定字符串路徑創(chuàng)建路徑
p = Path("documents") # PosixPath('documents')
使用正斜杠運算符進行路徑連接
data_dir = Path(".") / "data"
csv_file = data_dir / "file.csv"
print(data_dir) # data
print(csv_file) # data/file.csv
檢查路徑是否存在,可以使用布爾函數(shù) exists
data_dir.exists()
檢查文件是否存在
csv_file.exists()
使用 is_dir
或 is_file
函數(shù)來檢查是否為文件夾、文件
data_dir.is_dir()
csv_file.is_file()
大多數(shù)路徑都與當前運行目錄相關(guān),但某些情況下必須提供文件或目錄的絕對路徑,可以使用 absolute
csv_file.absolute() # PosixPath('/home/user/Downloads/data/file.csv')
如果仍然需要將路徑轉(zhuǎn)為字符串,可以調(diào)用 str(path)
強制轉(zhuǎn)換
str(Path.home()) # '/home/user'
現(xiàn)如今大多數(shù)庫都支持
Path
對象,包括sklearn
、pandas
、matplotlib
、seaborn
等
2. Path屬性
Path
對象有許多有用屬性,一起來看看這些示例,首先定義一個圖片路徑
image_file = Path("images/shadousheng.png").absolute() # PosixPath('/home/user/Downloads/images/midjourney.png')
先從 parent
開始,它將返回當前工作目錄的上一級
image_file.parent # PosixPath('/home/user/Downloads/images')
獲取文件名
image_file.name # 'shadousheng.png'
它將返回帶有后綴的文件名,若只想要前綴,則使用stem
image_file.stem # shadousheng
只想要后綴也很簡單
image_file.suffix # '.png'
如果要將路徑分成多個部分,可以使用 parts
image_file.parts # ('/', 'home', 'user', 'Downloads', 'images', 'shadousheng.png')
如果希望這些組件本身就是 Path
對象,可以使用 parents
屬性,它會創(chuàng)建一個生成器
for i in image_file.parents:
print(i)
# /home/user/Downloads/images
# /home/user/Downloads
# /home/user
# /home
# /
處理文件
想要創(chuàng)建文件并寫入內(nèi)容,不必再使用 open
函數(shù),只需創(chuàng)建一個 Path
對象搭配 write_text
或 write_btyes
即可
markdown = data_dir / "file.md"
# Create (override) and write text
markdown.write_text("# This is a test markdown")
讀取文件,可以 read_text
或 read_bytes
markdown.read_text() # '# This is a test markdown'
len(image_file.read_bytes()) # 1962148
但請注意, write_text
或 write_bytes
會覆蓋文件的現(xiàn)有內(nèi)容
# Write new text to existing file
markdown.write_text("## This is a new line")
# The file is overridden
markdown.read_text() # '## This is a new line'
要將新信息附加到現(xiàn)有文件,應該在 a
(附加)模式下使用 Path
對象的 open
方法:
# Append text
with markdown.open(mode="a") as file:
file.write("n### This is the second line")
markdown.read_text() # '## This is a new linen### This is the second line'
使用rename
重命名文件,如在當前目錄中重命名,file.md
變成了 new_markdown.md
renamed_md = markdown.with_stem("new_markdown")
markdown.rename(renamed_md) # PosixPath('data/new_markdown.md')
通過 stat().st_size
查看文件大小
# Display file size
renamed_md.stat().st_size # 49
查看最后一次修改文件的時間
from datetime import datetime
modified_timestamp = renamed_md.stat().st_mtime
datetime.fromtimestamp(modified_timestamp) # datetime.datetime(2023, 8, 1, 13, 32, 45, 542693)
st_mtime
返回一個自 1970 年 1 月 1 日以來的秒數(shù)。為了使其可讀,搭配使用 datatime
的 fromtimestamp
函數(shù)。
要刪除不需要的文件,可以 unlink
renamed_md.unlink(missing_ok=True)
如果文件不存在,將 missing_ok
設置為 True
則不會引起報錯
處理目錄
首先,看看如何遞歸創(chuàng)建目錄
new_dir.mkdir(parents=True, exist_ok=True)
默認情況下, mkdir
創(chuàng)建給定路徑的最后一個子目錄,如果中間父級不存在,則必須將 parents
設置為 True
達到遞歸創(chuàng)建目的
要刪除目錄,可以使用 rmdir
,如果給定的路徑對象是嵌套的,則僅刪除最后一個子目錄
new_dir.rmdir()
要在終端上列出 ls
等目錄的內(nèi)容,可以使用 iterdir
。結(jié)果將是一個生成器對象,一次生成一個子內(nèi)容作為單獨的路徑對象,和os.listdir
不同的是,它返回每個內(nèi)容的絕對路徑而不是名字
for p in Path.home().iterdir():
print(p)
# /home/user/anaconda3
# /home/user/.googleearth
# /home/user/.zcompdump
# /home/user/.ipython
# /home/user/.bashrc
要捕獲具有特定擴展名或名稱的所有文件,可以將 glob
函數(shù)與正則表達式結(jié)合使用。
例如,使用 glob("*.txt")
查找主目錄中所有文本文件
home = Path.home()
text_files = list(home.glob("*.txt"))
len(text_files) # 3
要遞歸搜索文本文件(即在所有子目錄中),可以glob 與 rglob
結(jié)合使用:
all_text_files = [p for p in home.rglob("*.txt")]
len(all_text_files) # 5116
以上就是Pathlib中常用方法,是不是感覺肥腸方便,如果有幫助到你就給個點贊三連吧,我是啥都生,下期再見