时间:2022-11-29 09:52:22 | 栏目:Python代码 | 点击:次
如果你还在为操作文件路径烦恼,不会使用os.path模块,那么是时候试试pathlib了。
pathlib 库从 python3.4 开始,到 python3.6 已经比较成熟。如果你的新项目可以直接用 3.6 以上,建议用 pathlib。相比于老式的 os.path 有几个优势:
常用的 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 |
需注意的是,返回的不是字符串,而是 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)
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)
from pathlib import Path print(Path.home()) # c:\Users\dell
from pathlib import Path # 1. is_file() 判断是不是文件 print(Path.cwd().is_file()) # False # 2.也可以实例化后调用 p = Path('./data.json') print(p.is_file()) # True
from pathlib import Path # 1. is_file() 判断是不是文件 print(Path.cwd().is_dir()) # True # 2.也可以实例化后调用 p = Path('./data.json') print(p.is_dir()) # False
from pathlib import Path # exists() 判断是否存在 p = Path('./data.json') print(p.exists()) # True or False
from pathlib import Path # 当前文件路径 p = Path(__file__) print(p) print(p.is_absolute()) # True
可以用类似 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())
比如在当前脚本的 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 会递归所有子目录 比如在当前脚本的 files 目录有以下文件夹和子文件
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')]) # []
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')]
from pathlib import Path p = Path('data.json') # math 检查匹配规则 print(p.match('*.json')) # True
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'
在当前脚本下创建一个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'
from pathlib import Path p = Path('yoyo/json') # mkdir 创建yoyo/json目录 p.mkdir(parents=True)
删除目录非常危险,并且没有提示,一定要谨慎操作
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 对读取和写入进行了简单的封装,不再需要重复去打开文件和管理文件的关闭了。
from pathlib import Path p = Path('yo.txt') p.write_text("hello world") print(p.read_text()) # hello world
file.write 操作使用的是 w 模式,如果之前已经有文件内容,将会被覆盖。
from pathlib import Path p = Path('yo.txt') p.write_text("hello world") print(p.read_text()) # hello world p.replace('xx.json')
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) # 移动到新的位置