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)  # 移动到新的位置
posted @ 2022-02-24 11:40  上海-悠悠  阅读(1111)  评论(0编辑  收藏  举报