文章目錄
- 簡介
- 現有問題
- 創建新路徑
- 創建目錄和重命名
- 遞歸列出某類型文件
- 打開多個文件並讀取內容
- 操作符
- 屬性和方法
- 路徑的每個位置 Path.parts
- 父目錄 Path.parents & Path.parent
- 文件名或目錄名 Path.name
- 文件名後綴 Path.suffixes & Path.suffix
- 不帶後綴文件名 Path.stem
- 是否爲絕對路徑 Path.is_absolute()
- 組合路徑 Path.joinpath(*other)
- 當前工作目錄 Path.cwd()
- 根目錄 Path.home()
- 是否存在路徑 Path.exists()
- 返回帶\~和\~user的路徑 Path.expanduser()
- 列出匹配的文件或目錄 Path.glob()
- 遞歸列出匹配的文件或目錄 Path.rglob()
- 是否爲目錄或文件 Path.is_dir() & Path.is_file()
- 列出路徑下的文件和目錄 Path.iterdir()
- 新建目錄 Path.mkdir()
- 打開文件 Path.open()
- 重命名 Path.rename()
- 覆蓋 Path.replace()
- 轉成絕對路徑 Path.resolve()
- 刪除目錄 Path.rmdir()
- 參考文獻
簡介
官方文檔將pathlib
稱爲面向對象的文件系統路徑,2019年Django將os.path
替換成了pathlib
。
os.path
一直是Python中處理路徑事實上的標準,但容易給人過於龐雜的感覺,而pathlib
可以完成其絕大多數的任務。
pathlib
在Python 3.4中引進,在Python 3.6中穩定。
現有問題
傳統上,Python將文件路徑表示爲常規文本字符串。然而,路徑實際上並不是字符串,因此完成功能需要使用多個模塊,包括os
、glob
和shutil
等庫。
將當前目錄所有.py文件複製到另一個目錄,需要使用多達三個模塊:
import os
import shutil
from glob import glob
for f in glob("*.py"):
path = os.path.join("./src", f) # 新路徑
shutil.copy(f, path)
創建新路徑
有文件file.txt,爲同一目錄下的file_another.txt構建路徑
os.path
from os.path import abspath, dirname, join
file_path = abspath("./file.txt") # 絕對路徑
base_dir = dirname(file_path) # 父目錄
file_another_path = join(base_dir, "file_another.txt") # 構成新路徑
print("file_path:", file_path)
print("base_dir:", base_dir)
print("file_another_path:", file_another_path)
pathlib
from pathlib import Path
file_path = Path("file.txt").resolve() # 絕對路徑
base_dir = file_path.parent # 父目錄
file_another_path = base_dir / "another_file.txt" # 構成新路徑
print("file_path:", file_path)
print("base_dir:", base_dir)
print("file_another_path:", file_another_path)
顯然用pathlib
更加便捷
創建目錄和重命名
os.path
import os
import os.path
os.makedirs(os.path.join("./src", "stuff"), exist_ok=True) # 構建目錄./src/stuff
os.rename("./src/stuff", "./src/config") # 將./src/stuff重命名爲./src/config
pathlib
from pathlib import Path
Path("./src/stuff").mkdir(parents=True, exist_ok=True) # 構建目錄./src/stuff
Path("./src/stuff").rename("./src/config") # 將./src/stuff重命名爲./src/config
遞歸列出某類型文件
假設目錄:
.
│ file.txt
│ test.py
│
└─src
└─config
submodule.py
__init__.py
列出所有.py文件
glob
from glob import glob
top_level_py_files = glob("./*.py")
all_py_files = glob("./**/*.py", recursive=True) # 遞歸
print(top_level_py_files)
print(all_py_files)
# ['.\\test.py']
# ['.\\test.py', '.\\src\\config\\submodule.py', '.\\src\\config\\__init__.py']
pathlib
from pathlib import Path
top_level_py_files = Path(".").glob("*.py")
all_py_files = Path(".").rglob("*.py") # 遞歸
print(list(top_level_py_files))
print(list(all_py_files))
# [WindowsPath('test.py')]
# [WindowsPath('test.py'), WindowsPath('src/config/submodule.py'), WindowsPath('src/config/__init__.py')]
打開多個文件並讀取內容
glob
from glob import glob
contents = []
for fname in glob("./**/*.py", recursive=True):
with open(fname, "r") as f:
contents.append(f.read())
print(contents)
pathlib
幾乎相同
from pathlib import Path
contents = []
for fname in Path(".").rglob("*.py"):
with open(fname, "r") as f:
contents.append(f.read())
print(contents)
操作符
使用/
取代os.path.join
創建子目錄
from pathlib import Path
base_dir = Path("src")
child_dir = base_dir / "config"
file_path = child_dir / "__init__.py"
print(file_path)
# src\config\__init__.py
屬性和方法
Path
descriptor:
parts: 每一層路徑
parent: 父目錄
parents: 所有父目錄
name: 文件名或目錄名
suffix: 文件名後綴
suffixes: 文件名後綴列表
stem: 不帶後綴文件名
function:
is_absolute: 是否爲絕對路徑
joinpath: 組合路徑
cwd: 當前工作目錄
home: 根目錄
exists: 是否存在路徑
expanduser: 返回帶~和~user的路徑
glob: 列出匹配的文件或目錄
rglob: 遞歸列出匹配的文件或目錄
is_dir: 是否爲目錄
is_file: 是否爲文件
iterdir: 列出路徑下的文件和目錄
mkdir: 新建目錄
open: 打開文件
rename: 重命名
replace: 覆蓋
resolve: 轉成絕對路徑
rmdir: 刪除目錄
路徑的每個位置 Path.parts
from pathlib import Path
file_path = Path("src/config/__init__.py")
print(file_path.parts)
# ('src', 'config', '__init__.py')
父目錄 Path.parents & Path.parent
from pathlib import Path
file_path = Path("src/config/__init__.py")
for parent in file_path.parents:
print(parent)
# src\config
# src
# .
print(file_path.parent)
# src\config
文件名或目錄名 Path.name
from pathlib import Path
print(Path("src/config/__init__.py").name)
print(Path("src/config").name)
# __init__.py
# config
文件名後綴 Path.suffixes & Path.suffix
在src/config/創建文件somefile.tar.gz
from pathlib import Path
file_path = Path("src/config/somefile.tar.gz")
print(file_path.suffixes)
print(file_path.suffix)
# ['.tar', '.gz']
# .gz
不帶後綴文件名 Path.stem
from pathlib import Path
print(Path("src/config/__init__.py").stem)
print(Path("src/config/somefile.tar.gz").stem)
# __init__
# somefile.tar
是否爲絕對路徑 Path.is_absolute()
from pathlib import Path
file_path = Path("src/config/somefile.tar.gz")
print(file_path.is_absolute())
# False
組合路徑 Path.joinpath(*other)
from pathlib import Path
file_path = Path("src").joinpath("config", "__init__.py")
print(file_path)
# src\config\__init__.py
當前工作目錄 Path.cwd()
from pathlib import Path
file_path = Path("src/config/somefile.tar.gz")
print(file_path.cwd())
# D:\code\test
根目錄 Path.home()
from pathlib import Path
file_path = Path("src/config/somefile.tar.gz")
print(file_path.home())
# C:\Users\Administrators
是否存在路徑 Path.exists()
from pathlib import Path
file_path = Path("src/config/aaaa.py")
print(file_path.exists())
# False
返回帶~和~user的路徑 Path.expanduser()
from pathlib import Path
file_path = Path("~/code/test/src/config/somefile.tar.gz")
print(file_path.expanduser())
# C:\Users\Administrators\code\test\src\config\somefile.tar.gz
列出匹配的文件或目錄 Path.glob()
from pathlib import Path
dir_path = Path("src/config/")
file_paths = dir_path.glob("*.py")
print(list(file_paths))
# [WindowsPath('src/config/submodule.py'), WindowsPath('src/config/__init__.py')]
遞歸列出匹配的文件或目錄 Path.rglob()
from pathlib import Path
dir_path = Path(".")
file_paths = dir_path.rglob("*.py")
print(list(file_paths))
# [WindowsPath('test.py'), WindowsPath('src/config/submodule.py'), WindowsPath('src/config/__init__.py')]
是否爲目錄或文件 Path.is_dir() & Path.is_file()
from pathlib import Path
dir_path = Path("src/config")
print(dir_path.is_dir()) # True
print(dir_path.is_file()) # False
file_path = Path("src/config/__init__.py")
print(file_path.is_dir()) # False
print(file_path.is_file()) # True
列出路徑下的文件和目錄 Path.iterdir()
from pathlib import Path
base_path = Path(".")
contents = [content for content in base_path.iterdir()]
print(contents)
# [WindowsPath('.idea'), WindowsPath('file.txt'), WindowsPath('src'), WindowsPath('test.py')]
新建目錄 Path.mkdir()
from pathlib import Path
dir_path = Path("src/other/side")
dir_path.mkdir(parents=True, exist_ok=True)
parents
爲False,父目錄不存在時拋出FileNotFoundError
exist_ok
爲False,該目錄存在時拋出FileExistsError
打開文件 Path.open()
同內置函數open()
from pathlib import Path
with Path("src/config/submodule.py") as f:
contents = open(f, "r")
for line in contents:
print(line)
重命名 Path.rename()
from pathlib import Path
file_path = Path("src/config/submodule.py")
file_path.rename(file_path.parent / "anothermodule.py")
覆蓋 Path.replace()
使用給定的目錄(文件)覆蓋原目錄(文件)
from pathlib import Path
file_path = Path("src/config/anothermodule.py")
file_path.replace(file_path.parent / "Dockerfile")
轉成絕對路徑 Path.resolve()
from pathlib import Path
file_path = Path("src/config/Dockerfile")
print(file_path.resolve())
# D:\code\test\src\config\Dockerfile
strict
設爲True,如果路徑不存在,則拋出FileNotFoundError
刪除目錄 Path.rmdir()
from pathlib import Path
file_path = Path("src/other/side")
file_path.rmdir()
如果目錄下不爲空,拋出OSError