Python开发中使用 pathlib 模块高效地操作目录及文件

pathlib module 介绍


编写访问目录及文件的代码是最常见的开发工作之一,如何快速方便地操作路径?pathlib 也许是一个很理想的工具。

pathlib 是Python内置库,Python 文档给它的定义是 Object-oriented filesystem paths(面向对象的文件系统路径)。pathlib 提供表示文件系统路径的类,其语义适用于不同的操作系统。

pathlib 不直接访问 OS 来操作 path,占内存少, 不用考虑底层是Linux还是Windows, 使代码可移植性更佳。

pathlib 模块各个class 之间的关系如下
Python开发中使用 pathlib 模块高效地操作目录及文件_第1张图片

通常, pathlib.Path 类就可以满足绝大部分场景使用。 当然如果只是 windows 应用开发,可以直接使用 PureWindowsPath, WindowsPath 等子类来编程,没必要化简就繁,毕竟 Path 类更通用。

基本使用方法


1) 获取当前路径、文件名、目录名:

from pathlib import Path  # 导入 pathlib Path 模块
print( Path.cwd())   # **获取当前路径

从路径中分解文件名

>>> p1 = Path("E:\智慧社区\tmp\log\2020-7-24\property.log")
>>> p1
WindowsPath('E:/智慧社区\tmp/log\x8s20-7-24/property.log')
>>> print(p1.stem)      # 获取文件名(不带扩展名)
property
>>> print(p1.name)      # 文件名 全名 
property.log
>>> print(p1.suffix)    # 文件名后缀
.log
>>> print(p1.anchor)
E:\
>>> print(p1.suffixes)
['.log']

用parents 属性来分解路径目录

>>> str(p1.parent)        # 获取当 path的完整目录名,不含文件名
'E:\\智慧社区\\tmp\\log\\2020-7-24'

# 获得各级目录名称,注意Path.parents[] ,多了1个s 
>>> p1.parents[0]
WindowsPath('E:/智慧社区/tmp/log/2020-7-24')
>>> p1.parents[1]
WindowsPath('E:/智慧社区/tmp/log')
>>> p1.parents[2]
WindowsPath('E:/智慧社区/tmp')
>>> p1.parents[3]
WindowsPath('E:/智慧社区')
>>> p1.parents[4]
WindowsPath('E:/')
>>> p1.parents

path 路径的分解也可以用 parts 方法

返回各目录元组

>>> p = PurePath('/usr/bin/python3')
>>> p.parts
('/', 'usr', 'bin', 'python3')

>>> p = PureWindowsPath('c:/Program Files/PSF')
>>> p.parts
('c:\\', 'Program Files', 'PSF')

PurePath 是 Path 的父类,所以 Path 对象也可以直接使用 parts 方法

2) 获取当前目录下的子目录,

>>> p = Path('.')
>>> [x for x in p.iterdir() if x.is_dir()]
[PosixPath('.hg'), PosixPath('docs'), PosixPath('dist'),
 PosixPath('__pycache__'), PosixPath('build')]

3) 获取指定路径下的文件

glob() 方法返回列表,元素也是Path类型
rglob() 方法可获取当前目录及所有子目录的相关内容

>>> list(p.glob('**/*.py'))
[PosixPath('test_pathlib.py'), PosixPath('setup.py'),
 PosixPath('pathlib.py'), PosixPath('docs/conf.py'),
 PosixPath('build/lib/pathlib.py')]

4) 路径拼接

用 / 操作符,或joinpath()方法,其结果仍是Path类型

强烈建议使用path的路径拼接功能,避免使用str 变量相加来组合,容易出错。

>>> p = Path('/etc')
>>> q = p / 'init.d' / 'reboot'
>>> q
PosixPath('/etc/init.d/reboot')
>>> q.resolve()
PosixPath('/etc/rc.d/init.d/halt')
>>> z = p.joinpath("1.conf")
PosixPath('/etc/1.conf')

5) 查询路径是目录还是文件

>>> q.exists()   # 路径是否存在
True
>>> q.is_dir()   # 是否为目录
False
>>> q.is_file()  # 是否为文件
True

6) 获取绝对路径

Path.resolve()

>>> p = Path()
>>> p
PosixPath('.')
>>> p.resolve()
PosixPath('/home/antoine/pathlib')

7) path 字符串化

当需要 print 或 把path做为 string 传递给一些函数时,需要把path 对象 转成 string后使用。 Windows下会自动使用 双反斜杠 \\
也可以使用Path类的内置方法__str__() 来获取其string值

>>> p = PurePath('/etc')
>>> str(p)
'/etc'
>>> p = PureWindowsPath('c:/Program Files')
>>> str(p)
'c:\\Program Files'

>>> q = Path("/home/peter/lianxi/p1.py")
PosixPath('/home/peter/lianxi/p1.py')
>>> q.__str__()
'/home/peter/lianxi/p1.py'

8) 直接用路径打开文件、写文件

用更少语句完成文件操作, 可避免转换成string, 再用python 方法 open 打开文件的过程。

>>> with q.open() as f: f.readline()
...
'#!/bin/bash\n'

Pure paths


pathlib.PurePath 不直接访问OS, 更有利于跨操作系统编程。 Path 是其子类

>>> PurePath('setup.py')     # Running on a Unix machine
PurePosixPath('setup.py')    # 表明运行在 Linux  上,底层自动用linux的目录

生成path

>>>PurePath('foo', 'some/path', 'bar')
PurePosixPath('foo/some/path/bar')
>>> PurePath('/etc', '/usr', 'lib64')
PurePosixPath('/usr/lib64')

两个路径比较

>>> PurePosixPath('foo') == PurePosixPath('FOO')
False

路径拼接操作符 : /

>>> p = PurePath('/etc')
>>> p
PurePosixPath('/etc')
>>> p / 'init.d' / 'apache2'
PurePosixPath('/etc/init.d/apache2')
>>> q = PurePath('bin')
>>> '/usr' / q
PurePosixPath('/usr/bin')

常用方法:

PurePath.as_posix()

返回 Linux风格的路径 (/):

PurePath.is_absolute()
判断当前路径是否为绝对路径

>>> PureWindowsPath('//some/share').is_absolute()
True

PurePath.joinpath( )

与 / 操作符的功能类似,用于路径拼接

>>> PurePosixPath('/etc').joinpath('passwd')
PurePosixPath('/etc/passwd')
>>> PurePosixPath('/etc').joinpath(PurePosixPath('passwd'))
PurePosixPath('/etc/passwd')
>>> PurePosixPath('/etc').joinpath('init.d', 'apache2')
PurePosixPath('/etc/init.d/apache2')

PurePath.match`(pattern)
判断 pattern 是否在目录路径内

如果匹配到了, 返回True,

>>> PurePath('a/b.py').match('*.py')
True
>>> PurePath('/a/b/c.py').match('b/*.py')
True
>>> PurePath('/a/b/c.py').match('a/*.py')
False

PurePath.with_name`(filename)
检查 访路径是否包含文件名
如果原路径不包含该文件名,则生成 ValueError 异常

>>> p = PureWindowsPath('c:/Downloads/pathlib.tar.gz')
>>> p.with_name('setup.py')
PureWindowsPath('c:/Downloads/setup.py')

Concrete paths


Patth是 PurePath的子类, 这个类代表 concrete path 实体路径
除了继承PurePath的方法外,下面表格列出来 Path的常用方法,以及与os 相关方法的对应关系,

os and os.path pathlib
os.path.abspath() Path.resolve()
os.chmod() Path.chmod()
os.mkdir() Path.mkdir()
os.makedirs() 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.listdir() Path.iterdir()
os.path.isdir() Path.is_dir()
os.path.isfile() Path.is_file()
os.path.islink() Path.is_symlink()
os.link() Path.hardlink_to()
os.symlink() Path.symlink_to()
os.readlink() Path.readlink()
os.path.relpath() Path.relative_to() 2
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

用Path方法来读写文件


Path 方法读写文件,可区分 Ascii 与 bytes 方式,编程效率更高

基本读写方法


>>> p = Path('setup.py')
>>> with p.open() as f:
...     f.readline()

>>> target.open().read()
'some text'

>>> p = Path('foo')
>>> p.open('w').write('some text')
9

ASCII方式读写文件

>>> p = Path('my_text_file')
>>> p.write_text('Text file contents')
18
>>> p.read_text()
'Text file contents'

二进制方式读写文件

>>> p = Path('my_binary_file')
>>> p.write_bytes(b'Binary file contents')
20
>>> p.read_bytes()
b'Binary file contents'

文件改名

>>> p = Path('foo')
>>> p.open('w').write('some text')
9
>>> target = Path('bar')
>>> p.rename(target)
PosixPath('bar')
>>> target.open().read()
'some text'

删除文件

Path.unlink (missing_ok=False)

Remove this file or symbolic link. If the path points to a directory, use Path.rmdir() instead.

默认 missing_ok = False, 如果文件不存在,会产生 FileNotFoundError 异常,设置为True, 则忽略该异常。


添加、删除目录

Path.mkdir() 生成子目录

>>> p1 = Path('/home/peter/lianxi')
>>> p3=p1/'test'
>>> p3.exists()
False
>>> p3.mkdir()
>>> p3.exists()
True

>>> p3
PosixPath('/home/peter/lianxi/test')

如上一级目录不存在,将产生1个 FileNotFoundError异常。
如目标目录已经存在,将产生1个 FileExistsError 异常

Path.rmdir() 删除目录, 该目录必须为空

总结建议


pathlib 可以用于替换 os.path 功能,并且更适用于跨平台编程,还提供了更高效的文件操作方式,值得学习。

你可能感兴趣的:(python,数据结构,django,virtualenv,tornado)