作者选择了 COVID-19 救援基金作为 Write for Donations计划的一部分接受捐款。
介绍
Python 3 包括 the pathlib
module用于操纵文件系统路径,无论操作系统如何。 pathlib
类似于 os.path
模块,但 pathlib
提供了一个更高的水平 - 而且往往更方便 - 界面比 os.path
。
例如,我们可以识别计算机上的文件 wave.txt
这个路径: `/Users/sammy/ocean/wave.txt. 操作系统略有不同地表示路径。
您可能会发现pathlib
模块有用,如果您在Python程序中:在文件系统上创建或移动文件,在文件系统上列出所有匹配给定的扩展或模式的文件,或基于原始字符串的集合创建操作系统适当的文件路径。
在本教程中,我们将讨论使用pathlib
模块来代表和操纵文件系统路径的一些方法。
前提条件
要充分利用本教程,建议您对Python编程有熟悉,您可以查看这些教程以获取必要的背景信息:
构建道路
实体
该pathlib
模块提供了几类(https://andsky.com/tech/tutorials/how-to-construct-classes-and-define-objects-in-python-3),但其中最重要的是Path
类,而Path
类的实例代表了我们计算机文件系统上的文件或目录的路径。
例如,以下代码实例化了一个Path
实例,该实例代表了一个wave.txt
文件的路径的一部分:
1from pathlib import Path
2
3wave = Path("ocean", "wave.txt")
4print(wave)
如果我们运行此代码,我们将收到如下的输出:
1[secondary_label Output]
2ocean/wave.txt
「從 pathlib 輸入路徑」將「Path」類別提供給我們的程式,然後「Path(「海洋」、「wave.txt」)」會進行一個新的「Path」實例。 打印出來的結果顯示,Python 已在我們給它兩個路徑組件之間添加了適當的操作系統分離器 /
:『ocean』和『wave.txt』。
<$>[注] 注: 根据您的操作系统,您的输出可能略有不同于本教程中显示的示例输出。
目前,分配给波
变量的Path
对象包含一个 relative path。 换句话说,在我们的文件系统中可能存在多个位置的ocean/wave.txt
。 例如,它可能存在于/Users/user_1/ocean/wave.txt
或/Users/user_2/research/ocean/wave.txt
,但我们尚未准确指定我们所指的位置。
您可以使用Path.home()
来获取当前用户的首页目录的绝对路径:
1home = Path.home()
2wave_absolute = Path(home, "ocean", "wave.txt")
3print(home)
4print(wave_absolute)
如果我们运行此代码,我们将收到大约如下的输出:
1[secondary_label Output]
2/Users/sammy
3/Users/sammy/ocean/wave.txt
<$>[注] 注: 如前所述,您的输出将取决于您的操作系统。
「Path.home()」返回一个具有绝对路径的「Path」实例到当前用户的主目录. 然后,我们将此「Path」实例和字符串「ocean」和「wave.txt」转移到另一个「Path」构建器中,以创建到「wave.txt」文件的绝对路径. 输出显示第一行是主目录,第二行是主目录加上「ocean/wave.txt」。
这个例子还说明了Path
类的一个重要特征:Path
构造器接受既有字符串和现有Path
对象。
让我们更仔细地看看Path
构建器中的两个字符串和Path
对象的支持:
1shark = Path(Path.home(), "ocean", "animals", Path("fish", "shark.txt"))
2print(shark)
如果我们运行这个Python代码,我们将收到类似于以下的输出:
1[secondary_label Output]
2/Users/sammy/ocean/animals/fish/shark.txt
鲨鱼
是我们使用Path
对象(Path.home()
和Path
(fish
,shark.txt
)和字符串(海洋
和动物
)构建的文件的Path
字符串。
访问文件属性
现在我们已经学会了如何构建Path
实例,让我们看看如何使用这些实例访问有关文件的信息。
我们可以使用名称
和足迹
属性来访问文件名和足迹:
1wave = Path("ocean", "wave.txt")
2print(wave)
3print(wave.name)
4print(wave.suffix)
运行此代码,我们将收到类似于以下的输出:
1[secondary_label Output]
2/Users/sammy/ocean/wave.txt
3wave.txt
4.txt
此输出显示,我们路径的末尾的文件名为wave.txt
,而该文件的接口为.txt
。
「Path」实例还提供「with_name」函数,允许您无缝创建具有不同名称的新「Path」对象:
1wave = Path("ocean", "wave.txt")
2tides = wave.with_name("tides.txt")
3print(wave)
4print(tides)
如果我们运行此操作,我们将收到如下的输出:
1ocean/wave.txt
2ocean/tides.txt
代码首先构建了一个Path
实例,该实例指向一个名为wave.txt
的文件,然后,我们在wave
上调用with_name
方法,以返回第二个Path
实例,该实例指向一个名为tides.txt
的新文件。
访问祖先
有时有助于访问包含给定的路径的目录,让我们考虑一个例子:
1shark = Path("ocean", "animals", "fish", "shark.txt")
2print(shark)
3print(shark.parent)
如果我们运行此代码,我们将收到看起来如下的输出:
1[secondary_label Output]
2ocean/animals/fish/shark.txt
3ocean/animals/fish
在Path
实例上的父母
属性返回给定文件路径的最直接的祖先. 在这种情况下,它返回包含shark.txt
文件的目录:海洋/动物/鱼
。
我们可以连续多次访问父母
属性,以穿越某个文件的祖先树:
1shark = Path("ocean", "animals", "fish", "shark.txt")
2print(shark)
3print(shark.parent.parent)
如果我们运行此代码,我们将收到以下输出:
1[secondary_label Output]
2ocean/animals/fish/shark.txt
3ocean/animals
输出与以前的输出类似,但现在我们通过第二次访问.parent
来跨越了另一个更高的水平。
使用 Glob 列出文件
还可以使用Path
类来使用glob
方法列出文件。
假设我们有一个目录结构,看起来像这样:
1└── ocean
2 ├── animals
3 │ └── fish
4 │ └── shark.txt
5 ├── tides.txt
6 └── wave.txt
一个海洋
目录包含文件tides.txt
和wave.txt
。我们有一个名为shark.txt
的文件嵌入海洋
目录,一个动物
目录和一个鱼
目录:海洋/动物/鱼
。
要列出海洋
目录中的所有.txt
文件,我们可以说:
1for txt_path in Path("ocean").glob("*.txt"):
2 print(txt_path)
这个代码会产生像这样的输出:
1[secondary_label Output]
2ocean/wave.txt
3ocean/tides.txt
該 "*.txt"
glob pattern找到所有以 .txt
結束的檔案。
<$>[注] 注: 如果您想复制本示例中显示的输出,则需要在您的计算机上模仿此处描述的目录结构。
我们还可以重复使用glob
方法,在ocean
目录和其所有子目录中列出所有.txt
文件,我们可以说:
1for txt_path in Path("ocean").glob("**/*.txt"):
2 print(txt_path)
如果我们运行此代码,我们将收到如下的输出:
1[secondary_label Output]
2ocean/wave.txt
3ocean/tides.txt
4ocean/animals/fish/shark.txt
地球图案的**
部分将重复匹配此目录和其下面的所有目录,所以,我们不仅在输出中有wave.txt
和tides.txt
文件,而且我们还收到shark.txt
文件,该文件被嵌入海洋/动物/鱼
。
计算机相对路径
我们可以使用 Path.relative_to
方法来计算彼此相对的路径. relative_to
方法在例如,您想要检索长程文件路径的一部分时非常有用。
考虑以下代码:
1shark = Path("ocean", "animals", "fish", "shark.txt")
2below_ocean = shark.relative_to(Path("ocean"))
3below_animals = shark.relative_to(Path("ocean", "animals"))
4print(shark)
5print(below_ocean)
6print(below_animals)
如果我们运行此操作,我们将收到如下的输出:
1[secondary_label Output]
2ocean/animals/fish/shark.txt
3animals/fish/shark.txt
4fish/shark.txt
在我们的示例中,我们计算Path
到shark.txt
相对于海洋
目录,然后相对于海洋
和动物
目录。
如果relative_to
无法计算一个答案,因为我们给它一个无关的路径,它会引出一个ValueError
:
1shark = Path("ocean", "animals", "fish", "shark.txt")
2shark.relative_to(Path("unrelated", "path"))
我们将收到从这个代码中提取的ValueError
例外,这将是这样的:
1[secondary_label Output]
2Traceback (most recent call last):
3 File "<stdin>", line 1, in <module>
4 File "/usr/local/lib/Python3.8/pathlib.py", line 899, in relative_to
5 raise ValueError("{!r} does not start with {!r}"
6ValueError: 'ocean/animals/fish/shark.txt' does not start with 'unrelated/path'
无关 / 路径
不是海洋 / 动物 / 鱼 / 鲨鱼.txt
的一部分,所以Python 无法为我们计算相对路径。
结论
pathlib
模块是Python标准图书馆(https://docs.python.org/3/library/)的强大组成部分,它允许我们在任何操作系统上快速操纵文件系统路径. 在本教程中,我们已经学会了使用一些pathlib
的关键实用程序来访问文件属性,列出与全球模式的文件,并穿过家长文件和目录。
pathlib
模块揭示了我们在本教程中没有涵盖的其他类和实用程序,现在你有一个基线,你可以使用pathlib
模块的文档(https://docs.python.org/3/library/pathlib.html)来了解更多关于其他可用的类和实用程序。
如果您对使用其他 Python 库感兴趣,请查看以下教程: