01
引言
大家好,我是AI算法之道!
Python是我最喜欢的编程语言之一,它向来以其简单性、多功能性和可读性而闻名。
然而,构建Python应用程序时,我经常会遇到一些路径上的问题,过去我曾经尝试过将路径拼接为字符串或者通过使用os和grob来拼凑路径。
好消息是,自从Python 3.4开始,Python中有了一个新模块:pathlib。一个模块就能完成所有路径相关的工作,并能在任何操作系统上无缝运行。可以毫不夸张的说,pathlib解决了我所有的痛点。
在本文中,我们将深入探讨Python中的路径问题,希望可以帮助到大家!
02
导入
pathlib 模块是标准 Python库的一部分,因此无需额外安装。
from pathlib import Path
03
文件夹结构
我创建了以下这个混乱的文件夹结构,作为本教程中的一个示例,
如上所示,该文件夹结构主要包括:
包含一些文件的主文件夹 data_4
一个子文件夹 (more_data) 包含更多文件 一个不包含任何文件的子文件夹(temp)
04
path object
Windows 上的 WindowsPosix Linux 和 Mac 上的 Posix
路径对象中有很多函数,可以方便地构建和检查路径。现在,让我们看一些实际例子中的效果。
05
获取路径
有时我们需要获取当前目录,则使用以下命令:
print(Path.cwd())
# Output
PosixPath('/home/pawjast/Documents/my github/medium/code')
print(Path.home())
# Output
PosixPath('/home/pawjast')
06
字符串转化为路径
有时我们需要将字符串转化为路径,则推荐以下两种方法:
尽量使用正斜线
my_path = Path.cwd() / "datasets" / "data_4"
注意:第一项必须是路径对象,斜线方法才会起作用。
使用 joinpath() 方法
my_path = Path.cwd().joinpath("datasets", "data_4")
两种情况下的输出结果,如下:
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4')
07
列出当前目录下的所有文件和文件夹
如果我们需要列出当前目录下的所有文件,在Pathlib中也有两种方法,分别如下:
使用 .iterdir() 函数
[path for path in my_path.iterdir()]
使用 .glob() 函数
list(my_path.glob("*"))
两种情况下的输出结果如下:
[PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/more_data'),
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/hi.md'),
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/data1.csv'),
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/data2.csv'),
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/abc.txt'),
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/cde.txt'),
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/temp')]
08
检查子目录
如果我们需要查看当前目录和其子目录下的文件,我们需要使用 .rglob() 方法(r 代表递归)。
list(my_path.rglob("*"))
这将同步展示子目录下的内容,如下:
[PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/more_data'),
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/hi.md'),
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/data1.csv'),
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/data2.csv'),
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/abc.txt'),
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/cde.txt'),
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/temp'),
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/more_data/abc.csv'),
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/more_data/go_deeper'),
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/more_data/whatshere.md'),
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/more_data/hello.html'),
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/more_data/yyy.txt'),
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/more_data/data3.csv'),
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/more_data/xxx.txt'),
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/more_data/go_deeper/abcd.py'),
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/more_data/go_deeper/surprise.csv'),
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/temp/dead_end')]
09
获取相对路径
如果要获取相对路径,我们需要定义路径的相对位置。
[path.relative_to(my_path) for path in my_path.rglob("*")]
这将输出如下:
[PosixPath('more_data'),
PosixPath('hi.md'),
PosixPath('data1.csv'),
PosixPath('data2.csv'),
PosixPath('abc.txt'),
PosixPath('cde.txt'),
PosixPath('temp'),
PosixPath('more_data/abc.csv'),
PosixPath('more_data/go_deeper'),
PosixPath('more_data/whatshere.md'),
PosixPath('more_data/hello.html'),
PosixPath('more_data/yyy.txt'),
PosixPath('more_data/data3.csv'),
PosixPath('more_data/xxx.txt'),
PosixPath('more_data/go_deeper/abcd.py'),
PosixPath('more_data/go_deeper/surprise.csv'),
PosixPath('temp/dead_end')]
10
仅获取文件
目前为止我们已经看到了几种生成文件、文件夹和子文件夹完整列表的方法。
让我们说得更具体一些。如果我们只想要文件的路径,就需要使用函数 .is_file() 来操作,代码如下:
# In the current folder - way 1
[path for path in my_path.iterdir() if path.is_file()]
或者,换种写法:
# In the current folder - way 2
[path for path in my_path.glob("*") if path.is_file()]
上述代码结果如下:
[PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/hi.md'),
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/data1.csv'),
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/data2.csv'),
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/abc.txt'),
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/cde.txt')]
这种方法也适用于子目录情形,代码如下:
[path for path in my_path.rglob("*") if path.is_file()]
结果如下:
[PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/hi.md'),
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/data1.csv'),
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/data2.csv'),
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/abc.txt'),
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/cde.txt'),
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/more_data/abc.csv'),
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/more_data/whatshere.md'),
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/more_data/hello.html'),
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/more_data/yyy.txt'),
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/more_data/data3.csv'),
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/more_data/xxx.txt'),
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/more_data/go_deeper/abcd.py'),
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/more_data/go_deeper/surprise.csv')]
11
仅获取文件夹
同样,大家也可以只列出所有的文件夹和子文件夹
[path for path in my_path.rglob("*") if path.is_dir()]
输出如下:
[PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/more_data'),
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/temp'),
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/more_data/go_deeper'),
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/temp/dead_end')]
注意:在这种情况下,顺序有点不对。请记住,我们将所有路径存储在一个列表中,排序可以解决这个问题。
sorted([path for path in my_path.rglob("*") if path.is_dir()])
输出如下:
[PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/more_data'),
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/more_data/go_deeper'),
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/temp'),
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/temp/dead_end')]
12
获取特定类型的文件
我们知道可以通过glob()函数获取特定类型的文件,这同样适用于pathlib中的 .glob() 和 .rglob()。
# Show `.csv` only
list(my_path.rglob("*.csv"))
输出如下:
[PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/data1.csv'),
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/data2.csv'),
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/more_data/abc.csv'),
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/more_data/data3.csv'),
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/more_data/go_deeper/surprise.csv')]
13
使用模式匹配
比方说,我们想要查找名称中包含 "abc "的所有文件。
list(my_path.rglob("*abc*"))
则输出如下:
[PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/abc.txt'),
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/more_data/abc.csv'),
PosixPath('/home/pawjast/Documents/my github/medium/code/datasets/data_4/more_data/go_deeper/abcd.py')]
14
总结
本文介绍了python中的pathlib库来操作路径的几个函数技巧,希望这些小技巧可以帮助到大家,提升大家的工作效率!
您学废了吗?
点击上方小卡片关注我
添加个人微信,进专属粉丝群!