5

Python 的路径操作 pathlib

 3 years ago
source link: https://blog.nodr.ink/python-pathlib/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Python 的路径操作 pathlib

发表于

2020 年 12 月 19 日 更新于 2021 年 1 月 31 日

阅读次数: 50

本文字数: 3.4k 阅读时长 ≈ 3 分钟

不会吧?不会吧?不会有人还在用 os.path 等模块来操作文件系统路径吧?难写又难读,看着就头痛。

今天我们将介绍 pathlib 模块。它同 os.path 模块一样也是 Python 标准库的一员。它提供了面向对象的路径操作,简洁易用、语义明确,让你真正体验到「人生苦短,我用 Python」的路径操作。

pathlib 模块中最重要的内容就是 Path 类,我们可以简单地使用一个路径字符串构造它,例如 Path('~/Downloads')。同时它提供了许多易于理解和使用的方法。这里将不逐一说明,使用时可在官方文档检索方法的详细说明。以下提供了它们与命令式风格的模块提供的函数的简单对照,但功能并不完全一致,可供参考。

以下操作可以用于构造 Path 实例。

legacy pathlib os.path.join() PurePath.joinpath(), PurePath.__truediv__() os.getcwd() Path.cwd() os.path.expanduser() Path.expanduser(), Path.home() os.path.abspath() Path.resolve() os.readlink() Path.readlink() os.listdir() Path.iterdir() glob.glob(), glob.iglob() Path.glob(), Path.rglob() N/A Path.with_name(), Path.with_stem(), Path.with_suffix()

以下操作可以用于查询 Path 实例对应的文件或目录的相关属性。

legacy pathlib os.path.basename() PurePath.name, PurePath.stem os.path.dirname() PurePath.parent, PurePath.parents os.path.splitext() PurePath.suffix, PurePath.suffixes os.path.isabs() PurePath.is_absolute() os.path.isdir() Path.is_dir() os.path.isfile() Path.is_file() os.path.islink() Path.is_symlink() os.path.samefile() Path.samefile() os.path.exists() Path.exists() os.stat() Path.stat(), Path.lstat(), Path.owner(), Path.group()

以下操作可以用于更改(包括创建、修改和删除)Path 实例对应的文件或目录。

legacy pathlib os.mkdir(), os.makedirs() Path.mkdir() os.link() Path.link_to() os.symlink() Path.symlink_to() os.rename() Path.rename() os.replace() Path.replace() os.chmod() Path.chmod(), Path.lchmod() os.rmdir() Path.rmdir() os.remove(), os.unlink() Path.unlink() N/A Path.touch()

输入输出操作

以下操作可以用于对(包括创建、修改和删除)Path 实例对应的文件进行输入输出。

legacy pathlib open() Path.open() open().read() Path.read_bytes(), Path.read_text() open().write() Path.write_bytes(), Path.write_text()

在这一部分,我们将在现实使用场景中使用 pathlib 做一些有实际意义的事情,以展示其强大的功能。

collect_images.py

from itertools import chain
from pathlib import Path

def collect_files_to_lines(source_folder, target_file, formats):
source_folder = Path(source_folder)
file_paths = (source_folder.rglob(f'*.{f}') for f in formats)
file_paths = sorted(chain.from_iterable(file_paths))
Path(target_file).write_text('\n'.join(map(str, file_paths)))
return len(file_paths)

if __name__ == '__main__':
num_images = collect_files_to_lines(
'images', 'images.txt', ['png', 'jpg', 'gif', 'bmp'])
print(f'{num_images = }')

collect_images.py 脚本将收集 images 目录下的所有以 pngjpggifbmp 为后缀的图片文件,按字典序排序后写入 images.txt 文件中。使用了 rglobwrite_text 方法。

copy_files.py

from itertools import chain
from pathlib import Path
import shutil

def copy_files_to_folder(source_folder, target_folder, formats):
source_folder, target_folder = Path(source_folder), Path(target_folder)
file_paths = (source_folder.rglob(f'*.{f}') for f in formats)
file_paths = sorted(chain.from_iterable(file_paths))
for source_path in file_paths:
relative_path = source_path.relative_to(source_folder)
target_path = target_folder.joinpath(relative_path)
target_path.parent.mkdir(parents=True, exist_ok=True)
shutil.copy(source_path, target_path)
return len(file_paths)

if __name__ == '__main__':
num_copied = copy_files_to_folder('source', 'target', ['txt'])
print(f'{num_copied = }')

copy_files.py 脚本将收集 source 目录下的所有以 txt 为后缀的文件,在保持原来的目录结构的情况下拷贝到 target 目录下。

脚本中使用了 relative_to 方法来获取相对路径以及 mkdir 方法的 parentsexist_ok 参数来方便地创建目录结构。另外,target_folder.joinpath(relative_path) 也可以等价地写成 target_folder / relative_path

随着 Python 版本的迭代,很多如 shutil.copy 这样接受路径字符串的函数,甚至包括一些第三方包(如 NumPy 和 Pillow)中的某些函数(如 numpy.savenumpy.loadPIL.Image.open),现在也可以接受路径对象了。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK