python筆記72 - 使用pathlib替代os.path


前言

如果你還在為操作文件路徑煩惱,不會使用os.path模塊,那么是時候試試pathlib了。

pathlib 庫

pathlib 庫從 python3.4 開始,到 python3.6 已經比較成熟。如果你的新項目可以直接用 3.6 以上,建議用 pathlib。相比於老式的 os.path 有幾個優勢:

  • 老的路徑操作函數管理比較混亂,有的是導入 os, 有的又是在 os.path 當中,而新的用法統一可以用 pathlib 管理。
  • 老用法在處理不同操作系統 win,mac 以及 linux 之間很吃力。換了操作系統常常要改代碼,還經常需要進行一些額外操作。
  • 老用法主要是函數形式,返回的數據類型通常是字符串。但是路徑和字符串並不等價,所以在使用 os 操作路徑的時候常常還要引入其他類庫協助操作。新用法是面向對象,處理起來更靈活方便。
  • pathlib 簡化了很多操作,用起來更輕松。

常用的 pathlib 和 os 對比圖

操作 os and os.path pathlib
絕對路徑 os.path.abspath Path.resolve
修改權限 os.chmod Path.chmod
創建目錄 os.mkdir Path.mkdir
重命名 os.rename Path.rename
移動 os.replace Path.replace
刪除目錄 os.rmdir Path.rmdir
刪除文件 os.remove, os.unlink Path.unlink
工作目錄 os.getcwd Path.cwd
是否存在 os.path.exists Path.exists
用戶目錄 os.path.expanduser Path.expanduser and Path.home
是否為目錄 os.path.isdir Path.is_dir
是否為文件 os.path.isfile Path.is_file
是否為連接 os.path.islink Path.is_symlink
文件屬性 os.stat Path.stat, Path.owner, Path.group
是否為絕對路徑 os.path.isabs PurePath.is_absolute
路徑拼接 os.path.join PurePath.joinpath
文件名 os.path.basename PurePath.name
上級目錄 os.path.dirname PurePath.parent
同名文件 os.path.samefile Path.samefile
后綴 os.path.splitext PurePath.suffix

pathlib 獲取文件路徑

Path.cwd 獲取當前文件夾路徑

需注意的是,返回的不是字符串,而是 WindowsPath 對象

from pathlib import Path

# 1.可以直接調用類方法.cwd()
print(Path.cwd())  # C:\Users\dell\PycharmProjects\untitled3\demo

# 2.也可以實例化后調用
p = Path('./')
print(p.cwd()) # C:\Users\dell\PycharmProjects\untitled3\demo
print(type(p.cwd()))  # <class 'pathlib.WindowsPath'>

獲取當前文件路徑

from pathlib import Path

# 當前文件路徑
p = Path(__file__)
print(p)

獲取 Path 對象絕對路徑

from pathlib import Path

# 當前文件路徑
p = Path('data.json')
print(p)  # data.json 對象
print(p.absolute())  # C:\Users\dell\PycharmProjects\untitled3\demo\data.json

一些常用的獲取文件屬性

from pathlib import Path

# 當前文件路徑
p = Path(__file__)
print(p.absolute())   # 獲取絕對路徑
print(p.resolve())    # 獲取絕對路徑
print(p.name)   # 獲取文件名稱 'a1117.py'
print(p.stem)    # 只要文件名,不要后綴 a1117
print(p.suffix)  # 獲取文件 后綴.py
print(p.suffixes)  # 文件所有的猴子 ['.py']
print(p.parts)  # 拆分('C:\\', 'Users', 'dell', 'PycharmProjects', 'untitled3', 'demo', 'a1117.py')
print(p.parent)  # C:\Users\dell\PycharmProjects\untitled3\demo
print(p.parent.parent)  # C:\Users\dell\PycharmProjects\untitled3
print(p.parents)  # 所有的父級 <WindowsPath.parents>
print(p.anchor)  # 錨,目錄前面的部分 C:\ 或者 /

獲取上層,上上層目錄

from pathlib import Path

# .parent 獲取上一層
print(Path.cwd().parent)

# 實例化后調用 .parent
p = Path('./')
print(p.cwd().parent)

獲取上上層使用鏈式方法調用 .parent.parent

from pathlib import Path

# .parent 獲取上一層
print(Path.cwd().parent.parent)

# 實例化后調用 .parent
p = Path('./')
print(p.cwd().parent.parent)

獲取用戶home目錄

from pathlib import Path
print(Path.home())  # c:\Users\dell

判斷文件,文件夾

is_file()判斷是不是文件

from pathlib import Path

# 1.  is_file() 判斷是不是文件
print(Path.cwd().is_file())  # False


# 2.也可以實例化后調用
p = Path('./data.json')
print(p.is_file())  # True

is_dir() 判斷是否是文件夾

from pathlib import Path

# 1.  is_file() 判斷是不是文件
print(Path.cwd().is_dir())  # True


# 2.也可以實例化后調用
p = Path('./data.json')
print(p.is_dir())  # False

exists() 判斷文件 或文件夾是否存在

from pathlib import Path

# exists() 判斷是否存在
p = Path('./data.json')
print(p.exists())  # True or False

is_absolute() 判斷是否是絕對路徑

from pathlib import Path

# 當前文件路徑
p = Path(__file__)
print(p)
print(p.is_absolute())  # True

joinpath 拼接目錄

可以用類似 os.path.join 的方法

from pathlib import Path

# 當前文件路徑
p = Path('./')
print(p.absolute())  # C:\Users\dell\PycharmProjects\untitled3\demo
print(p.joinpath('data.json'))  # data.json
print(p.joinpath('data.json').absolute())   # C:\Users\dell\PycharmProjects\untitled3\demo\data.json
# 拼接多層
print(p.joinpath('files', 'data.json'))   # files\data.json
print(p.joinpath('files', 'data.json').absolute())  # C:\Users\dell\PycharmProjects\untitled3\demo\files\data.json

pathlib 支持用 / 拼接路徑, 這種語法估計用的人很少

from pathlib import Path

# 當前文件路徑
p = Path('./')
# / 拼接
new_path = p / 'files' / 'data.json'
print(new_path.absolute())

iterdir()遍歷文件目錄

比如在當前腳本的 files 目錄有以下文件夾和子文件

.iterdir() 遍歷某個目錄下的所有路徑(文件和子目錄)

from pathlib import Path

# 當前文件路徑
p = Path('files')
for i in p.iterdir():
    print(i.absolute())

"""運行結果:
C:\Users\dell\PycharmProjects\untitled3\demo\files\json
C:\Users\dell\PycharmProjects\untitled3\demo\files\username.txt
C:\Users\dell\PycharmProjects\untitled3\demo\files\yaml
"""

如果只需獲取文件夾,可以加個判斷.is_dir()

from pathlib import Path

# 當前文件路徑
p = Path('files')
print([i for i in p.iterdir() if i.is_dir()])  # [WindowsPath('files/json'), WindowsPath('files/yaml')]

也可以用.is_file獲取文件對象

from pathlib import Path

# 當前文件路徑
p = Path('files')
print([i for i in p.iterdir() if i.is_file()])  # [WindowsPath('files/username.txt')]

glob() 和 rglob() 模式匹配(正則表達式)

使用模式匹配(正則表達式)匹配指定的路徑。glob 只會匹配當前目錄下, rglob 會遞歸所有子目錄
比如在當前腳本的 files 目錄有以下文件夾和子文件

glob 只會匹配當前目錄下

from pathlib import Path

p = Path('files')
# glob 只會遍歷查找當前目錄
print(p.glob('*.txt'))  # <generator object Path.glob at 0x000001A44565A518>
print([i for i in p.glob('*.txt')])  # [WindowsPath('files/username.txt')]
print([i for i in p.glob('*.yml')])  # []

rglob 會遞歸所有子目錄

from pathlib import Path

p = Path('files')
# glob 只會遍歷查找當前目錄
print(p.rglob('*.txt'))  # <generator object Path.glob at 0x000001A44565A518>
print([i for i in p.rglob('*.txt')])  # [WindowsPath('files/username.txt')]
print([i for i in p.rglob('*.yml')])  # [WindowsPath('files/yaml/aa.yml'), WindowsPath('files/yaml/bb.yml')]

match() 檢查路徑是否符合規則

from pathlib import Path

p = Path('data.json')
# math 檢查匹配規則
print(p.match('*.json'))  # True

創建文件操作

touch() 創建文件

from pathlib import Path

p = Path('xx.json')
p.touch()   # 創建一個xx.json

當文件已經存在的時候,p.touch() 也不會報錯,因為默認參數 exist_ok=True
如果設置 exist_ok=False, 文件已經存在,touch就會報錯了

from pathlib import Path

p = Path('xx.json')
p.touch(exist_ok=False)   # 創建一個xx.json

拋出異常FileExistsError: [Errno 17] File exists: 'xx.json'

mkdir() 創建目錄

在當前腳本下創建一個yoyo目錄

from pathlib import Path

p = Path('yoyo')
# mkdir 創建yoyo目錄
p.mkdir()

如果想一次性創建多層目錄 'yoyo/json'

from pathlib import Path

p = Path('yoyo/json')
# mkdir 創建yoyo/json目錄
p.mkdir()

此時會拋出異常FileNotFoundError: [WinError 3] 系統找不到指定的路徑。: 'yoyo\json'

遞歸創建目錄mkdir(parents=True)

from pathlib import Path

p = Path('yoyo/json')
# mkdir 創建yoyo/json目錄
p.mkdir(parents=True)

刪除文件操作

刪除目錄非常危險,並且沒有提示,一定要謹慎操作

rmdir() 一次只刪除一級目錄,且當前目錄必須為空。

from pathlib import Path

p = Path('yoyo/json')
# mkdir 創建yoyo/json目錄
p.rmdir()
from pathlib import Path

p = Path('files/username.txt')
p.unlink()

文件讀寫操作

pathlib 對讀取和寫入進行了簡單的封裝,不再需要重復去打開文件和管理文件的關閉了。

  • .read_text() 讀取文本
  • .read_bytes() 讀取 bytes
  • .write_text() 寫入文本
  • .write_bytes() 寫入 tytes
from pathlib import Path

p = Path('yo.txt')
p.write_text("hello world")
print(p.read_text())  # hello world

file.write 操作使用的是 w 模式,如果之前已經有文件內容,將會被覆蓋。

修改文件

replace() 移動文件

from pathlib import Path

p = Path('yo.txt')
p.write_text("hello world")
print(p.read_text())  # hello world

p.replace('xx.json')

with_name() 重命名文件

from pathlib import Path

p = Path('hello.txt')
p.write_text("hello world")
print(p.read_text())  # hello world

# 重命名為一個新的文件對象
new_file = p.with_name('x.txt')
print(new_file)
p.replace(new_file)  # 移動到新的位置


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM