一、pathlib 模块简介

        pathlib 是Python 3.4版本开始加入的 路径处理模块。它将路径本身变成一个对象,这个对象自带各种操作方法,代码写起来更直观、优雅。但 pathlib 不会取代 os.path。

        os.path 的路径 是字符串(‘C:/Users/test.txt')

        pthlib 的路径是对象(Path(’C:/Users/test.txt')

        根据官方文档,pathlib 模块共分为 6个部分:

                PurePath:

                        纯路径。

                        拼接路径、取文件名、取后缀、判断路径是否以指定的后缀结尾等。

                        不读取硬盘(不能创建、删除文件),且不区分操作系统,因此运行速度快

                PurePosixPath、PureWindowsPath:

                        用于处理不同操作系统的斜杠

                        PurePosixPath:专门处理 / 斜杠的路径,Linux系统的 /home/user

                        PureWindowsPath:专门处理 \ 反斜杠的路径,Windows系统的 C:\Users

                Path:

                        实体路径

                        继承 PurePath 的所有能力,并增加访问磁盘的功能,因此可创建、删除文件夹,读取文件内容等。

                PosixPath、WindowsPath:

                        是 Path 在不同操作系统下的具体实现

                        在 Windows 系统中导入 Path,那么 Path 即为 WindowsPath,同样的在Linux系统中导入 Path 即为 PosixPath

        我们要学习的便是 Path

二、Path 的常用方法

        1、系统方法

               (1)Path.cwd()

                        获取当前所在目录

                        它自动识别了操作系统的类型,并在返回值中体现出来。和 os 模块的用法基本差不多

                        

                (2)Path.home()

                        获取用户主目录

                        os 模块获取用户主目录可通过 os.environ 获取到环境变量,然后根据操作系统的类型通过 os.environ['USERPROFILE'] (Windows系统)、os.environ['HOME'] (Linux系统)来获取。

                

                (3)Path.chdir()

                        Path.chdir() 是 Ppython 3.11版本以后的新特性

                        使用方法((由于我的系统环境问题,无法复现):

                                p = Path(r"E:\os_path_2")

                                p.chdir()

                (4)Path.expanduser()

                        将路径字符串中的 ~ 替换成当前用户的主目录路径,作用和 os.path.expanduser('~')完全一样,区别在于 Path.expanduser()返回的是一个 Path 对象。

                (5)Path.resolve()

                        将路径解析为绝对路径

                        示例1:将相对路径替换成绝对路径

                        在 E:\os_path_2 目录下有一个 test.txt的文件,先切换到目录下(由于环境问题,我使用的是 os.chdir()

                        示例2:将路径中的 .. 和 . 消除

                        .. :返回上一级;. :当前目录

                        原始路径为:"E:\os_path_2\test\next_file\test2\test_2.txt"

                        得到的结果并不是原始路径,而且还不相同,那么说明一个情况:Path.resolve() 只负责处理,不负责判断是否存在。如果需要判断文件路径是否存在则需要使用到 .exists() 来进行判断。

                        

                        再来说一个 .resolve()的参数

                        Path.resolve() 默认参数为 strict=False,可指定为 strict=True

                        什么作用?再来试一下:

                                路径不存在时会报错,相当于使用 .exists(),只不过一个返回的是 False,一个直接抛出 FileNotFoundError 错误。

                (6)Path.absolute()

                        负责补全路径头,不负责清理路径中的 .. 或 .

                        通过上面这个示例可以看出 Path.resolve() 和 Path.asbolute() 的不同:

                                .absolute():是将当前所在目录的路径补全在了 p4 的前面,没有处理路径中的 ..

                                .resolve():将当前所在目录的路径补在了 p4 的前面,而且处理了路径中的 ..

        2、查询与判断

                Path.exists() :判断路径是否存在

                Path.is_dir():判断是否为目录

                Path.is_file():判断是否为普通文件

                Path.is_symlink():判断是否为符号连接

                Path.is_absolute():判断是否为绝对路径

                Path.stat():获取文件状态信息

                Path.lstat():获取文件状态信息(不跟踪符号链接)

                Path.owner():获取文件所有者(Unix)

                Path.group():获取文件所属组(Unix)

                Path.readlink():读取符号链接的目标路径

        3、遍历与搜索

                Path.iterdir() 

                        遍历指定目录下的所有内容,得到的是一个可迭代的对象

                        如果目录中有子目录不会再遍历子目录

                Path.glob() :

                        通配符搜索当前目录,可查找特定的文件

                Path.rglob():

                        递归通配符搜索所有子目录

                        查找指定目录下包括子目录中所有指定类型的文件

                Path.walk():

                        递归遍历目录树

                        Path.walk() 是 Python 3.12以后引入的一个新方法,它和 os.walk() 的用法基本一致,但返回的是生成器。可通过 for root, dirs, files 来循环。

                        root:当前目录的完整绝对路径

                        dirs:当前目录下所有子目录

                        files:当前目录下所有文件

                        通过示例可以看到 Path.walk() 是逐层遍历的过程

        4、创建与删除

                Path.mkdir(mode=0o777, parents=True, exist_ok=True):

                        创建目录

                        mode=0o777 :

                                用于设置目录的权限(不常用)

                        parents=False/True:

                                是否自动创建路径中所有不存在的父目录

                                当parents=True时相当于os.makedirs()

                        exist_ok=False/True:

                                如果目标目录已存在,是否报错

                

                Path.touch(mode=0o777, exist_ok=True):

                        创建文件或更新时间戳

                Path.rmdir():

                        删除空目录

                Path.unlink(missing_ok=False):

                        删除文件

        

        5、文件操作

                Path.open(mode='r'):打开文件,和os模块的一样

                Path.read_text(encoding=None):读取文本文件

                Path.write_text(data, encoding=None):写入文本文件,覆盖写入

                Path.read_test() 和 Path.write_text() 只适合操作小文件,如果需要操作大文件则需要使用 Path.open()。

                在使用时务必加上 encoding 参数,以免报错。

        6、重命名与移动

                Path.rename(target):重命名文件或目录

                Path.replace(target):重命名并覆盖已存在的目录

        以上就是 Path 的常用方法,我将它们分成了6类,基本可以满足日常需求。

四、一个示例

        os模块学习过程中,做了一个桌面文件整理的脚本,在学习 pathlib 后,对其进行了修改。

        根据文件扩展名对桌面文件进行归类整理。

# import os
from pathlib import Path
import shutil
import datetime

# 1、定义变量

# 获取当前用户主目录
home = Path.home()

# 定义source_path 变量,赋值为桌面路径 
source_path = home / "Desktop"

# 定义目标主目录
desc_path = home / "Desktop" / "files"

# 通过字典定义不同的文件类型归类到指定的分类目录,"suffix_***" 名称可以自定义,文件分类也可自定义
suffix_dict = {
    "suffix_txt": [".txt"],
    "suffix_zip" : [".tar.gz", ".zip", ".rar", ".7z", ".tar", ".gz", ".bz2", ".xz"],
    "suffix_doc" : [".doc", ".docx"],
    "suffix_pdf" : [".pdf"],
    "suffix_excel" : [".xls", ".xlsx"],
    "suffix_powerpoint" : [".ppt", ".pptx"],
    "suffix_image" : [".jpg", ".jpeg", ".png", ".gif", ".bmp", ".svg", ".webp"],
    "suffix_video" : [".mp4", ".avi", ".mkv", ".wmv", ".mov", ".flv", ".webm"],
    "suffix_audio" : [".mp3", ".wav", ".aac", ".ogg", ".flac"],
    "suffix_exe" : [".exe", ".msi"]
}

def makedirs_file():
    # 创建主目录
    # .mkdir(parents=True, exist_ok=True)中, parents=True 表示创建父目录, exist_ok=True 表示如果目录已存在则不创建,不会报错
    desc_path.mkdir(parents=True, exist_ok=True)

    # 创建子目录
    for key in suffix_dict.keys():
        (desc_path / key).mkdir(parents=True, exist_ok=True)


def get_and_move_file(source_path):
    # 创建目录
    makedirs_file()


    # 遍历桌面
    for file_path in source_path.iterdir():
        # 如果脚本在 Desktop 下,则跳过,即不移动脚本文件
        if file_path.name == Path(__file__).name:
            continue
        
        # 只处理文件,不处理文件夹
        if not file_path.is_file():
            continue
        
        # 获取文件名和扩展名
        name_without_ext = file_path.stem
        ext = file_path.suffix

        # 查找属于哪个分类
        target_key = None
        for key, suffix_list in suffix_dict.items():
            if ext in suffix_list:
                target_key = key
                break

        # 如果找不到匹配,则跳过
        if target_key is None:
            print(f"{file_path.name} 无法识别的文件类型")
            continue
        
        # 定义目标路径
        target_folder = desc_path / target_key
        target_path = target_folder / file_path.name

        # 重名处理,如果存在重名的文件,则以当前系统时间重命名文件
        if target_path.exists():
            timestamp = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
            new_name = f"{name_without_ext}_{timestamp}{ext}"
            target_path = target_folder / new_name
            print(f"⚠️ {file_path.name} 已存在,重命名为 {new_name}")
        
        # 移动文件
        try:
            shutil.move(file_path, target_path)
            print(f"✅ 移动 {file_path.name} → {target_folder}")
        except Exception as e:
            print(f"❌ 移动失败:{file_path.name},错误:{e}")
    
if __name__ == "__main__":
    get_and_move_file(source_path)


学习中,如有不足还请指正!

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐