pathlib模块详解

在编程中处理文件的读写操作时免不了要和文件路径打交道,甚至有时候为了完成某些场景功能会变的有些繁琐,以前在Python中操作文件路径,我们更多的时候是使用os模块。

而到了Python3时代后,Python3的系统标准库pathlib模块的 Path 对路径的操作会更简单。甚至可以说pathlib已经可以完全替代os.path,它完全采用面向对象的编程方式,因为Python 文档给它的定义是 Object-oriented filesystem paths(面向对象的文件系统路径),其语义适用于不同的操作系统,它继承纯路径但也提供I/O化操作,在处理配置路径方面十分简单。

基础用法

在过去,文件的路径是纯字符串,现在它会是一个pathlib.Path对象:

1
2
3
4
5
6
7
8
9
In : from pathlib import Path

In : p = Path('/home/ubuntu')

In : p
Out: PosixPath('/home/ubuntu')

In : str(p)
Out: '/home/ubuntu'

使用str函数可以把一个Path对象转化成字符串。


返回当前工作目录路径和Home路径

在pathlib里一切都是面向对象的,只需要调用指定的方法就可以了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from pathlib2 import Path

# 获取当前目录
current_path = Path.cwd()
print(current_path)

# 输出如下:
# /Users/Anders/Documents/

#获取Home目录
home_path = Path.home()
print(home_path)

# 输出如下:
# /Users/Anders

父目录操作

你可以看到想要获取一个路径下上级的父目录可以非常方便的直接使用面向对象的方式**.parent**就行了,如果还想上一级就继续以子对象继续操作parent属性就可以了,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
from pathlib2 import Path

# 获取当前目录
current_path = Path.cwd()

# 获取上级父目录
print(current_path.parent)

# 获取上上级父目录
print(current_path.parent.parent)

# 获取上上上级父目录
print(current_path.parent.parent.parent)

# 获取上上上上级父目录
print(current_path.parent.parent.parent.parent)

# 获取上上上上级父目录
print(current_path.parent.parent.parent.parent.parent)

# 输出如下:
# /Users/Anders/Documents/Jupyter
# /Users/Anders/Documents
# /Users/Anders
# /Users
# /

当然路径是十分长的,而且在特定的场合我如果想获得每一级的父目录呢,贴心的pathlib已经帮我们想到了,使用parents属性就可以遍历整个父目录了,如下例子的效果和上面的例子是完全一样的,但是就变的非常简便。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 获取当前目录

from pathlib2 import Path

current_path = Path.cwd()
for p in current_path.parents:
print(p)

# 输出如下:
# /Users/Anders/Documents/Jupyter
# /Users/Anders/Documents
# /Users/Anders
# /Users
# /

文件名操作

常用的文件名操作属性如下:

  • name 目录的最后一个部分
  • suffix 目录中最后一个部分的扩展名
  • suffixes 返回多个扩展名列表
  • stem 目录最后一个部分,没有后缀
  • with_name(name) 替换目录最后一个部分并返回一个新的路径
  • with_suffix(suffix) 替换扩展名,返回新的路径,扩展名存在则不变
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
from pathlib2 import Path

# 返回目录中最后一个部分的扩展名
example_path = Path('/Users/Anders/Documents/abc.gif')
print(example_path.suffix)

# 输出如下:
# .gif

# 返回目录中多个扩展名列表
example_paths = Path('/Users/Anders/Documents/abc.tar.gz')
print(example_paths.suffixes)

# 输出如下:
# ['.tar', '.gz']

# 返回目录中最后一个部分的文件名(但是不包含后缀)
example_path = Path('/Users/Anders/Documents/abc.gif')
print(example_path.stem)

# 输出如下:
# abc

# 返回目录中最后一个部分的文件名
example_path = Path('/Users/Anders/Documents/abc.gif')
print(example_path.name)

# 输出如下:
# abc.gif

# 替换目录最后一个部分的文件名并返回一个新的路径
new_path1 = example_path.with_name('def.gif')
print(new_path1)

# 输出如下:
# /Users/Anders/Documents/def.gif

# 替换目录最后一个部分的文件名并返回一个新的路径
new_path2 = example_path.with_suffix('.txt')
print(new_path2)

# 输出如下:
# /Users/Anders/Documents/abc.txt

路径拼接和分解
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from pathlib2 import Path

#直接传进一个完整字符串
example_path1 = Path('/Users/Anders/Documents/powershell-2.jpg')

#也可以传进多个字符串
example_path2 = Path('/', 'Users', 'dongh', 'Documents', 'python_learn', 'pathlib_', 'file1.txt')

#也可以利用Path.joinpath()
example_path3 = Path('/Users/Anders/Documents/').joinpath('python_learn')

#利用 / 可以创建子路径

example_path4 = Path('/Users/Anders/Documents')
example_path5 = example_path4 / 'python_learn/pic-2.jpg'

遍历文件夹

我们可以在路径对象后面直接使用**iterdir()**方法,该方法返回一个生成器,我们可以循环遍历出所有指定目录下的目录路径。

1
2
3
4
5
6
7
8
9
10
11
12
from pathlib2 import Path

# 返回目录中最后一个部分的扩展名
example_path = Path('/Users/Anders/Documents')
[path for path in example_path.iterdir()]

# 输出如下:
# [PosixPath('/Users/Anders/Documents/abc.jpg'),
# PosixPath('/Users/Anders/Documents/book-master'),
# PosixPath('/Users/Anders/Documents/Database'),
# PosixPath('/Users/Anders/Documents/Git'),
# PosixPath('/Users/Anders/Documents/AppProjects')]

创建文件夹和删除文件夹

关于这里的创建文件目录mkdir方法接收两个参数:

  • parents:如果父目录不存在,是否创建父目录。
  • exist_ok:只有在目录不存在时创建目录,目录已存在时不会抛出异常。
1
2
3
4
5
6
7
8
9
from pathlib2 import Path

example_path = Path('/Users/Anders/Documents/test1/test2/test3')

# 创建文件目录,在这个例子中因为本身不存在test1,test2,test3,由于parents为True,所以都会被创建出来。
example_path.mkdir(parents = True, exist_ok = True)

# 删除路径对象目录,如果要删除的文件夹内包含文件就会报错
example_path.rmdir()

关于文件的判断还有很多相关属性,罗列如下:

  • is_dir() 是否是目录
  • is_file() 是否是普通文件
  • is_absolute() 是否是绝对路径
  • resolve() 返回一个新的路径,这个新路径就是当前Path对象的绝对路径,如果是软链接则直接被解析
  • absolute() 也可以获取绝对路径,但是推荐resolve()
  • exists() 该路径是否指向现有的目录或文件:

如上,已经基本列举了路径处理中常用的各类操作,其实pathlib的方便和强大远不止于此,具体信息可以参见官方文档:https://docs.python.org/3.4/library/pathlib.html