Python学习系列 -初探标准库之pathlib库

系列文章目录

第一章 初始 Python
第二章 认识 Python 变量、类型、运算符
第三章 认识 条件分支、循环结构
第四章 认识 Python的五种数据结构
第五章 认识 Python 函数、模块
第六章 认识面向对象三大特性
第七章 初探标准库之os库
第八章 初探标准库之pathlib库



文章开篇

Python的魅力,犹如星河璀璨,无尽无边;人生苦短、我用Python!


Python其强大的标准库和丰富的第三方库,恰似一片生机勃勃的森林,为开发者们提供了源源不断的资源和支持;
在这片广袤的“森林”中,隐藏着许多Python标准库中的珍贵模块,如os、sys、re等;它们如同森林中的璀璨明珠,熠熠生辉,为开发者的工作提供着不可或缺的支持
在Python的生态系统中,有许多备受赞誉的第三方库,如NumPy、Pandas、openpyxl、requests、selenium、pyqt等,这些库如同森林中的珍稀物种,以其独特的功能和卓越的性能,助力开发者们更高效地完成工作;
无论是处理字符串、读写文件这样的基础任务,还是并发编程、数据分析等高级挑战,Python的标准库和三方库都能应对自如,满足各种需求;


pathlib标准库简介

pathlib标准库是在Python 3.4及以后版本引入的一个用于处理文件路径和目录的类库
pathlib标准库是以面向对象的方式来访问文件系统,支持跨平台工作,会自动适配不同的操作系统的文件分隔符
pathlib和os.path的区别、优点和缺点如下:

  • 区别:
    在Python 3.4版本之前,涉及路径相关操作,几乎都用os模块解决,尤其是os.path这个子模块非常有用;
    在Python 3.4版本之后,pathlib成为标准库模块,使用对象来表示路径,丰富了路径处理的方式;
  • 优点:
    pathlib使得在不同操作系统之间切换非常简单;
    pathlib实现统一管理,解决了传统操作导入模块不统一问题;
    pathlib是跨平台的、面向对象的,路径处理更灵活方便,解决了传统路径和字符串并不等价的问题;
    pathlib使得代码更加易读和可维护,尤其在涉及到多平台的应用时,可以避免手动拼接文件路径的麻烦和错误。
  • 缺点:
    pathlib标准库在Python 3.4及以后版本才有,版本兼容性较差(无法向前兼容)

pathlib分类图

pathlib分类图

pathlib提供了多个类来表示不同类型的路径,主要分为PurePath类Path类,其中最常用的就是Path类;
Path类实例化后可以用于访问文件和目录的属性、方法,比如文件大小和修改时间,以及创建、重命名、删除等操作

  • PurePath类
    PurePath访问实际文件系统的纯路径,只负责对路径字符串执行操作;
    PurePath有两个子类,即PurePosixPath和PathWindowsPath;
    前者用于操作UNIX(包括 Mac OS X)风格的路径;
    后者用于操作Windows风格的路径。
  • Path类
    Path访问实际文件系统的真正路径,可用于判断文件是否存在、是否为文件、是否为目录等。
    Path有两个子类,即PosixPath和WindowsPath;
    前者用于操作UNIX(包括 Mac OS X)风格的路径;
    后者用于操作Windows风格的路径。
  • PurePath和Path的区别:
    Path 是 PurePath 的子类;
    PurePath 处理的仅是字符串;
    Path 则会真正访问底层的文件路径;
  • UNIX 和 Windows 风格路径区别:
    UNIX 风格路径的根路径是斜杠(/);
    Windows 风格路径的根路径是盘符(c:);
    UNIX 风格的路径的分隔符是斜杠(/);
    Windows 风格路径的分隔符是反斜杠(\);

文本重点讲解pathlib标准库下的常用类 —— Windows风格的Path类
Path示意图

pathlib.path与os.path方法对应关系

pathlib.path与os.path方法对应关系

PurePath 类属性和方法

请添加图片描述


获取文件名称

from pathlib import Path

file_path = "/Users/PythonWorkspace/第49课:第三方库/CASE06:Pathlib/PathlibUtils.py"

p = Path(file_path)

print(f"获取文件名称:{p.name}")        # 获取文件名称:PathlibUtils.py

获取文件前缀

from pathlib import Path

file_path = "/Users/PythonWorkspace/第49课:第三方库/CASE06:Pathlib/PathlibUtils.py"

p = Path(file_path)

print(f"获取文件名称前缀:{p.stem}")     # 获取文件名称前缀:PathlibUtils

获取文件后缀

from pathlib import Path

file_path = "/Users/PythonWorkspace/第49课:第三方库/CASE06:Pathlib/PathlibUtils.py"

p = Path(file_path)

print(f"获取文件名称后缀:{p.suffix}")   # 获取文件名称后缀:.py

# 还有一个方法需要说明,suffixes,是用来获取文件名称中所有的.后缀,示例如下:
file_path1 = "第49课:第三方库/CASE06:Pathlib/PathlibUtils.p1.p2.py"

p1 = Path(file_path1)
print(f"获取文件名称后缀:{p1.suffixes}")   # 获取文件名称后缀:['.p1', '.p2', '.py']

获取文件上级目录

from pathlib import Path

file_path = "/Users/PythonWorkspace/第49课:第三方库/CASE06:Pathlib/PathlibUtils.py"

p = Path(file_path)

print(f"获取文件的当前目录:{p.parent}")          # 获取文件的当前目录:/Users/PythonWorkspace/第49课:第三方库/CASE06:Pathlib
print(f"获取文件的上级目录:{p.parent.parent}")   # 获取文件的上级目录:/Users/PythonWorkspace/第49课:第三方库
print(f"获取文件的上上级目录:{p.parent.parent.parent}")           # 获取文件的上上级目录:/Users/PythonWorkspace
print(f"获取文件的上上上级目录:{p.parent.parent.parent.parent}")   # 获取文件的上上上级目录:/Users
print(f"获取文件的上上上上级目录:{p.parent.parent.parent.parent.parent}")           # 获取文件的上上上上级目录:/(此时已经到达路径顶级)
print(f"获取文件的上上上上上级目录:{p.parent.parent.parent.parent.parent.parent}")  # 获取文件的上上上上级目录:/(即使超过路径的顶级也不会异常)


获取文件所属及其父文件夹

from pathlib import Path

file_path = "/Users/PythonWorkspace/第49课:第三方库/CASE06:Pathlib/PathlibUtils.py"

p = Path(file_path)

print(f"获取当前文件所属文件夹及其父文件夹:{p.parents}")   # 获取当前文件所属文件夹及其父文件夹:<PosixPath.parents>

for idx, folder_path in enumerate(p.parents):
    print(f"No.{idx}: {folder_path}")
    # No.0: /Users/PythonWorkspace/第49课:第三方库/CASE06:Pathlib(第一个索引是当前目录)
    # No.1: /Users/PythonWorkspace/第49课:第三方库
    # No.2: /Users/PythonWorkspace
    # No.3: /Users
    # No.4: /(最后一个索引是顶级目录)

获取当前工作目录

# 已知当前py文件所在目录是:/Users/PythonWorkspace/第49课:第三方库/CASE06:Pathlib/PathlibUtils.py
# 我们使用os库和pathlib库获取一下当前工作文件的目录
path_1 = Path.cwd()
path_2 = os.getcwd()

print(f"Path.cwd()方法: {path_1}")    # Path.cwd()方法: /Users/PythonWorkspace/第49课:第三方库/CASE06:Pathlib
print(f"os.getcwd()方法: {path_2}")   # os.getcwd()方法: /Users/PythonWorkspace/第49课:第三方库/CASE06:Pathlib

获取用户Home目录路径

from pathlib import Path

file_path = "/TestPath/test.py"

p = Path(file_path)

print(f"获取用户home路径: {p.home()}")    # 获取用户home路径: /Users
print(f"获取用户home路径: {Path.home()}") # 获取用户home路径: /Users

# 请注意,home路径不是指传入路径的顶级目录,而是当前计算机存储个人文件和配置文件的主目录

相对路径转为绝对路径

from pathlib import Path

file_path = "./PathlibUtils.py"

print(f"相对路径转为绝对路径前: {Path(file_path)}")            # 相对路径转为绝对路径前: PathlibUtils.py
print(f"相对路径转为绝对路径后: {Path(file_path).resolve()}")  # 相对路径转为绝对路径后: /Users/PythonWorkspace/第49课:第三方库/CASE06:Pathlib/PathlibUtils.py


文件绝对路径按照/进行分割

from pathlib import Path

file_path = "/Users/PythonWorkspace/第49课:第三方库/CASE06:Pathlib/PathlibUtils.py"

p = Path(file_path)

print(f"将文件的绝对路径按照/进行分割,返回一个tuple:{p.parts}")   # 将文件的绝对路径按照/进行分割,返回一个tuple:('第49课:第三方库', 'CASE06:Pathlib', 'PathlibUtils.py')

for idx, element in enumerate(p.parts):
    print(f"No.{idx}: {element}")
    # No.0: /(第一个索引是顶级目录)
    # No.1: Users
    # No.2: PythonWorkspace
    # No.3: 第49课:第三方库
    # No.4: CASE06:Pathlib
    # No.5: PathlibUtils.py(最后一个索引是末尾目录或文件)

检查目录或文件是否存在

from pathlib import Path

file_path = "/Users/PythonWorkspace/第49课:第三方库/CASE06:Pathlib/PathlibUtils.py"
dire_path = "/Users/PythonWorkspace/第49课:第三方库/CASE06:Pathlib12345"

print(f"检查目标路径的文件是否存在: {Path(file_path).exists()}")  # 检查目标路径的文件是否存在: True
print(f"检查目标路径的目录是否存在: {Path(dire_path).exists()}")  # 检查目标路径的目录是否存在: False

检查指定路径是不是目录或文件

from pathlib import Path

file_path = "/Users/PythonWorkspace/第49课:第三方库/CASE06:Pathlib/PathlibUtils.py"

print(f"检查指定路径是不是文件: {Path(file_path).is_file()}")  # 检查指定路径是不是文件: True
print(f"检查指定路径是不是目录: {Path(file_path).is_dir()}")   # 检查指定路径是不是目录: False

获取文件的详细信息

from pathlib import Path

file_path = "/Users/PythonWorkspace/第49课:第三方库/CASE06:Pathlib/PathlibUtils.py"

p = Path(file_path)

print(f"获取文件详细信息: {p.stat()}")    # os.stat_result(st_mode=33188, st_ino=12404114, st_dev=16777231, st_nlink=1, st_uid=501, st_gid=20, st_size=3796, st_atime=1708666696, st_mtime=1708666695, st_ctime=1708666695)
print(f"获取文件字节大小: {p.stat().st_size}")      # 获取文件字节大小: 3796
print(f"获取文件创建时间: {p.stat().st_ctime}")     # 获取文件创建时间: 1708666695.965969
print(f"获取文件上次修改时间: {p.stat().st_mtime}")  # 获取文件上次修改时间: 1708666695.965969

获取指定路径下的一级目录和文件


from pathlib import Path

file_path = "/Users/PythonWorkspace/第49课:第三方库"

path_object = Path(file_path)       # <class 'pathlib.PosixPath'>
path_iter = path_object.iterdir()   # <class 'generator'>

print(f"Path类的生成器对象: {path_iter}")  # Path类的生成器对象: <generator object Path.iterdir at 0x7fb1e0041430>

# 迭代指定目录对象下的子文件名(只会得到路径下的一级目录,不会访问子集)
for idx, element in enumerate(path_iter):
    print(f"No.{idx}: {element}")
    # No.0: /Users/PythonWorkspace/第49课:第三方库/CASE01:PyQt
    # No.1: /Users/PythonWorkspace/第49课:第三方库/CASE01:Pandas
    # No.2: /Users/PythonWorkspace/第49课:第三方库/CASE05:OS
    # No.3: /Users/PythonWorkspace/第49课:第三方库/CASE05:openpyxl
    # No.4: /Users/PythonWorkspace/第49课:第三方库/CASE04:Argparser
    # No.5: /Users/PythonWorkspace/第49课:第三方库/CASE02:PyGUI
    # No.6: /Users/PythonWorkspace/第49课:第三方库/CASE06:Pathlib

获取指定路径下符合规则的一级目录和文件

from pathlib import Path

pattern = "第*课:*"
file_path = "/Users/PythonWorkspace/"
glob_generator = Path(file_path).glob(pattern)

# 遍历返回的对象 -> 返回的是绝对路径
for idx, element in enumerate(glob_generator):
    print(f"No.{idx}: {element}")
    # /Users/PythonWorkspace/第01课:初识Python
    # /Users/PythonWorkspace/第02课:第一个Python程序
    # /Users/PythonWorkspace/第03课:Python语言元素之变量
    # /Users/PythonWorkspace/第04课:Python语言元素之运算符
    # /Users/PythonWorkspace/第05课:分支结构
    # /Users/PythonWorkspace/第06课:循环结构
    # /Users/PythonWorkspace/第07课:分支和循环结构的应用
    # /Users/PythonWorkspace/第08课:常用数据结构之列表
    # /Users/PythonWorkspace/第09课:常用数据结构之元组
    # /Users/PythonWorkspace/第10课:常用数据结构之字符串
    # /Users/PythonWorkspace/第11课:常用数据结构之集合
    # /Users/PythonWorkspace/第12课:常用数据结构之字典
    # /Users/PythonWorkspace/第13课:函数和模块
    # /Users/PythonWorkspace/第14课:函数的应用
    # /Users/PythonWorkspace/第15课:函数使用进阶
    # /Users/PythonWorkspace/第16课:函数的高级应用
    # /Users/PythonWorkspace/第17课:面向对象编程入门
    # /Users/PythonWorkspace/第18课:面向对象编程进阶
    # /Users/PythonWorkspace/第19课:面向对象编程应用
    # /Users/PythonWorkspace/第20课:Python标准库初探
    # /Users/PythonWorkspace/第20课:Python标准库初探\demo
    # /Users/PythonWorkspace/第21课:文件读写和异常处理
    # /Users/PythonWorkspace/第22课:对象的序列化和反序列化
    # /Users/PythonWorkspace/第23课:用Python读写CSV文件
    # /Users/PythonWorkspace/第24课:用Python读写Excel文件-1
    # /Users/PythonWorkspace/第25课:用Python读写Excel文件-2
    # /Users/PythonWorkspace/第26课:用Python操作Word文件和PowerPoint
    # /Users/PythonWorkspace/第27课:用Python操作PDF文件
    # /Users/PythonWorkspace/第28课:用Python处理图像
    # /Users/PythonWorkspace/第29课:用Python发送邮件和短信
    # /Users/PythonWorkspace/第30课:正则表达式的应用
    # /Users/PythonWorkspace/第31课:网络数据采集概述
    # /Users/PythonWorkspace/第32课:用Python获取网络资源
    # /Users/PythonWorkspace/第33课:用Python解析HTML页面
    # /Users/PythonWorkspace/第34课:Python中的并发编程-1
    # /Users/PythonWorkspace/第35课:Python中的并发编程-2
    # /Users/PythonWorkspace/第36课:Python中的并发编程-3
    # /Users/PythonWorkspace/第37课:并发编程在爬虫中的应用
    # /Users/PythonWorkspace/第38课:抓取网页动态内容
    # /Users/PythonWorkspace/第39课:爬虫框架Scrapy简介
    # /Users/PythonWorkspace/第40课:关系型数据库和MySQL概述
    # /Users/PythonWorkspace/第41课:SQL详解之DDL
    # /Users/PythonWorkspace/第42课:SQL详解之DML
    # /Users/PythonWorkspace/第43课:SQL详解之DQL
    # /Users/PythonWorkspace/第44课:SQL详解之DCL
    # /Users/PythonWorkspace/第45课:索引
    # /Users/PythonWorkspace/第46课:视图+函数+过程
    # /Users/PythonWorkspace/第47课:MySQL新特性
    # /Users/PythonWorkspace/第48课:Python程序接入MySQL数据库
    # /Users/PythonWorkspace/第49课:第三方库
    # /Users/PythonWorkspace/第50课:WEB框架

删除文件


from pathlib import Path

file_path = "/Users/PythonWorkspace/第49课:第三方库"

# 查看路径下所有的txt文件
for idx, element in enumerate(Path(file_path).glob("*.txt")):
    print(f"No.{idx}: {element}")
    # No.0: /Users/PythonWorkspace/第49课:第三方库/test1.txt
    # No.1: /Users/PythonWorkspace/第49课:第三方库/test2.txt
    # No.2: /Users/PythonWorkspace/第49课:第三方库/test3.txt

    Path(element).unlink()  # 上述文件都会被删除

try:
    # 删除不存在的文件
    Path("./not_exist.txt").unlink()        # FileNotFoundError: [Errno 2] No such file or directory: 'not_exist.txt'
except Exception as e:
    print(f"删除文件发生错误,原因为: {e}")     # 删除文件发生错误,原因为: [Errno 2] No such file or directory: 'not_exist.txt'


删除目录

from pathlib import Path

file_path = "/Users/PythonWorkspace/第49课:第三方库/CASE06:Pathlib"

for idx, element in enumerate(Path(file_path).glob("test_*")):
    print(f"No.{idx}: {element}")
    # No.0: /Users/PythonWorkspace/第49课:第三方库/CASE06:Pathlib/test_directory_3
    # No.1: /Users/PythonWorkspace/第49课:第三方库/CASE06:Pathlib/test_directory_2
    # No.2: /Users/PythonWorkspace/第49课:第三方库/CASE06:Pathlib/test_directory_1

    Path(element).rmdir()   # 上述都会被删除(如果目录内存在内容,则会抛出异常)

读写文件

from pathlib import *

file_path = "/Users/PythonWorkspace/第49课:第三方库/CASE06:Pathlib/write_test.txt"

with Path(file_path).open('w') as f:  # 创建并打开文件
	f.write('你的男朋友是个盖世垃圾,他将会脚踏七彩祥云迎娶你的闺蜜~')  # 写入内容

with open(file_path, "r") as fo:
	print(f"读取的文件内容为:{fo.read()}")

真实案例封装


1.获取指定路径下的文件

功能作用:

  • 获取指定路径下所有的一级文件
  • 获取指定路径下指定后缀的一级文件
  • 获取指定路径下所有的子集文件
  • 获取指定路径下指定后缀的所有子集文件
from pathlib import *


def get_file_list(path: str, directory_off: bool = False, file_suffixes: list = []) -> list:
    """
    获取指定路径下的文件列表
    :param path: 目标路径,可以是文件或文件夹路径。
    :param directory_off: 是否包括子目录中的文件。默认为False,即只包括当前目录中的文件。
    :param file_suffixes: 需要过滤的文件后缀列表。如果不提供或为空列表,则包括所有文件。例如:['.xlsx', '.xls']。
    :return: 符合条件的文件列表。
    """
    # 检查目标路径是否存在
    if not Path(path).exists():
        raise FileNotFoundError(f"文件或目录不存在: {path}")
    
    # 初始化列表,记录最终查找到的文件结果
    return_file_list = []

    # 如果未指定文件后缀列表,则根据目标路径下的文件获取所有后缀
    if not file_suffixes:
        if directory_off:
            pattern = "**/*.*"
        else:
            pattern = "*.*"
        [file_suffixes.append(Path(f).suffix) for f in Path(path).glob(pattern) if Path(f).is_file()]
        file_suffixes = list(set(file_suffixes))

    # 如果目标路径是文件夹
    if Path(path).is_dir():
        # 如果需要包括子目录中的文件
        if directory_off:
            # 遍历指定后缀的文件
            for i in file_suffixes:
                [return_file_list.append(str(f)) for f in Path(path).glob(f"**/*{i}")]
        else:
            # 只遍历当前目录中的指定后缀文件
            [return_file_list.append(str(f)) for f in Path(path).iterdir() if
             Path(f).is_file and f.suffix in file_suffixes]

    # 如果目标路径是文件
    elif Path(path).is_file():
        return_file_list = [path]

    # 去除临时文件
    for temp_file in return_file_list[:]:
        if "~$" in Path(temp_file).stem:
            return_file_list.remove(temp_file)

    return return_file_list


if __name__ == '__main__':
    file_path = "/Users/PythonWorkspace/第49课:第三方库/CASE06:Pathlib"

    # file_list = get_file_list(file_path, True)
    # file_list = get_file_list(file_path, True, [".py"])
    # file_list = get_file_list(file_path, False)
    file_list = get_file_list(file_path, False, [".txt"])
    for file in file_list:
        print(file)

2.处理文件或目录名称
from pathlib import *
from datetime import datetime


def out_path_handle(path, join_str="", file_suffix=""):
    """
    处理指定路径的文件或目录名称
    :param path:        目标路径,可以是文件或文件夹路径。
    :param join_str:    文件或目录名称需要拼接的标记元素。
    :param file_suffix: 默认返回实际文件后缀,如需修改则给定新后缀,例如:'.xlsx'。
    :return: 处理后的路径。
    """
    # 检查目标路径是否存在
    if not Path(path).exists():
        raise FileNotFoundError(f"文件或目录不存在: {path}")

    # 如果未指定文件或目录拼接标记元素,则获取当前时间戳
    if join_str == "":
        join_str = datetime.now().strftime("%Y%m%d_%H%M%S_%f")
    # 如果指定的文件或目录拼接元素以_结尾,则在_拼接当前时间戳
    elif join_str[-1] == "_":
        join_str = join_str + datetime.now().strftime("%Y%m%d_%H%M%S_%f")

    # 获取指定路径的父级目录
    parent_path = Path(path).parent
    # 使用指定路径的末级元素拼接标记元素
    temp_path = Path(path).stem + "_" + join_str
    if Path(path).is_dir():
        return parent_path.joinpath(temp_path)
    elif Path(path).is_file():
        # 如果未指定文件后缀,则获取文件实际后缀
        if file_suffix == "":
            file_suffix = Path(path).suffix
        return parent_path.joinpath(temp_path + file_suffix)


if __name__ == '__main__':
    file_path = "/Users/PythonWorkspace/第49课:第三方库/CASE06:Pathlib/test_1"

    print(out_path_handle(file_path))
    # /Users/PythonWorkspace/第49课:第三方库/CASE06:Pathlib/temp_20240224_115603_655674.xlsx

    print(out_path_handle(file_path, "待处理"))
    # /Users/PythonWorkspace/第49课:第三方库/CASE06:Pathlib/temp_待处理.xlsx

    print(out_path_handle(file_path, "待处理_"))
    # /Users/PythonWorkspace/第49课:第三方库/CASE06:Pathlib/temp_待处理_20240224_120431_421562.xlsx

    print(out_path_handle(file_path, "待处理_", ".txt"))
    # /Users/PythonWorkspace/第49课:第三方库/CASE06:Pathlib/temp_已处理_20240224_120544_098640.txt


总结

Python中的pathlib模块是处理路径操作的行业标准,凭借其丰富的功能和简洁的语法,它显著提升了路径操作的便捷性和效率;
pathlib不仅简化了文件和目录的创建、删除、查询和遍历等操作,还通过直观的对象导向方法减少了路径处理中的常见错误;
此外,pathlib的跨平台兼容性确保了代码在不同操作系统上的稳定性和可移植性

  • 37
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

需要休息的KK.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值