The author selected the COVID-19 Relief Fund to receive a donation as part of the Write for DOnations program.
作者选择了COVID-19救济基金来接受捐赠,这是Write for DOnations计划的一部分。
介绍 (Introduction)
Python 3 includes the pathlib
module for manipulating filesystem paths agnostically whatever the operating system. pathlib
is similar to the os.path
module, but pathlib
offers a higher level—and often times more convenient—interface than os.path
.
Python 3包含pathlib
模块,用于在任何操作系统下pathlib
不可知论的方式处理文件系统路径。 pathlib
与os.path
模块类似,但是pathlib
提供了比os.path
更高级别的接口,并且常常是更方便的接口。
We can identify files on a computer with hierarchical paths. For example, we might identify the file wave.txt
on a computer with this path: /Users/sammy/ocean/wave.txt
. Operating systems represent paths slightly differently. Windows might represent the path to the wave.txt
file like C:\Users\sammy\ocean\wave.txt
.
我们可以识别具有分层路径的计算机上的文件。 例如,我们可以在具有以下路径的计算机上标识文件wave.txt
: /Users/ sammy /ocean/wave.txt
。 操作系统代表的路径略有不同。 Windows可能表示wave.txt
文件的路径,例如C:\Users\ sammy \ocean\wave.txt
。
You might find the pathlib
module useful if in your Python program you are creating or moving files on the filesystem, listing files on the filesystem that all match a given extension or pattern, or creating operating system appropriate file paths based on collections of raw strings. While you might be able to use other tools (like the os.path
module) to accomplish many of these tasks, the pathlib
module allows you to perform these operations with a high degree of readability and minimal amount of code.
如果在Python程序中正在创建或移动文件系统上的文件,列出与给定扩展名或模式都匹配的文件系统上的文件,或者基于原始字符串的集合创建适合操作系统的文件路径,则可能会发现pathlib
模块很有用。 虽然您可以使用其他工具(例如os.path
模块)来完成许多任务,但pathlib
模块使您能够以高度的可读性和最少的代码执行这些操作。
In this tutorial, we’ll go over some of the ways to use the pathlib
module to represent and manipulate filesystem paths.
在本教程中,我们将介绍一些使用pathlib
模块表示和操作文件系统路径的方法。
先决条件 (Prerequisites)
To get the most out of this tutorial, it is recommended to have some familiarity with programming in Python 3. You can review these tutorials for the necessary background information:
为了充分利用本教程,建议您熟悉Python 3的编程。您可以查看以下教程以获取必要的背景信息:
构造Path
实例 (Constructing Path
Instances)
The pathlib
module provides several classes, but one of the most important is the Path
class. Instances of the Path
class represent a path to a file or directory on our computer’s filesystem.
pathlib
模块提供了几个类 ,但是最重要的一个是Path
类。 Path
类的实例表示我们计算机文件系统上文件或目录的路径。
For example, the following code instantiates a Path
instance that represents part of the path to a wave.txt
file:
例如,以下代码实例化一个Path
实例,该实例代表wave.txt
文件的路径的wave.txt
:
from pathlib import Path
wave = Path("ocean", "wave.txt")
print(wave)
If we run this code, we’ll receive output like the following:
如果运行此代码,我们将收到类似以下的输出:
Output
ocean/wave.txt
from pathlib import Path
makes the Path
class available to our program. Then Path("ocean", "wave.txt")
instantiates a new Path
instance. Printing the output shows that Python has added the appropriate operating system separator of /
between the two path components we gave it: "ocean"
and "wave.txt"
.
from pathlib import Path
使Path
类可用于我们的程序。 然后, Path("ocean", "wave.txt")
实例化一个新的Path
实例。 打印输出显示Python在我们给它的两个路径组件"ocean"
和"wave.txt"
之间添加了/
的适当的操作系统分隔符。
Note: Depending on your operating system, your output may vary slightly from the example outputs shown in this tutorial. If you are running Windows, for example, your output for this first example might look like ocean\wave.txt
.
注意:根据您的操作系统,您的输出可能与本教程中显示的示例输出略有不同。 例如,如果您正在运行Windows,则第一个示例的输出可能类似于ocean\wave.txt
。
Currently, the Path
object assigned to the wave
variable contains a relative path. In other words, ocean/wave.txt
might exist in several places on our filesystem. As an example, it may exist in /Users/user_1/ocean/wave.txt
or /Users/user_2/research/ocean/wave.txt
, but we haven’t specified exactly which one we are referring to. An absolute path, by contrast, unambiguously refers to one location on the filesystem.
当前,分配给wave
变量的Path
对象包含一个相对路径 。 换句话说, ocean/wave.txt
可能存在于我们文件系统上的多个位置。 例如,它可能存在于/Users/ user_1 /ocean/wave.txt
或/Users/ user_2 /research/ocean/wave.txt
,但我们没有确切指定我们要指的是哪一个。 相反, 绝对路径明确指向文件系统上的一个位置。
You can use Path.home()
to get the absolute path to the home directory of the current user:
您可以使用Path.home()
获取当前用户的主目录的绝对路径:
home = Path.home()
wave_absolute = Path(home, "ocean", "wave.txt")
print(home)
print(wave_absolute)
If we run this code, we’ll receive output roughly like the following:
如果运行此代码,我们将大致收到如下所示的输出:
Output
/Users/sammy
/Users/sammy/ocean/wave.txt
Note: As mentioned earlier, your output will vary depending on your operating system. Your home directory, of course, will also be different than /Users/sammy
.
注意:如前所述,您的输出将取决于您的操作系统。 当然,您的主目录也将不同于/Users/ sammy
。
Path.home()
returns a Path
instance with an absolute path to the current user’s home directory. We then pass in this Path
instance and the strings "ocean"
and "wave.txt"
into another Path
constructor to create an absolute path to the wave.txt
file. The output shows the first line is the home directory, and the second line is the home directory plus ocean/wave.txt
.
Path.home()
返回带有当前用户主目录绝对路径的Path
实例。 然后,我们将此Path
实例以及字符串"ocean"
和"wave.txt"
到另一个Path
构造函数中,以创建wave.txt
文件的绝对路径。 输出显示第一行是主目录,第二行是主目录加ocean/wave.txt
。
This example also illustrates an important feature of the Path
class: the Path
constructor accepts both strings and preexisting Path
objects.
此示例还说明了Path
类的重要功能: Path
构造函数同时接受字符串和预先存在的Path
对象。
Let’s look at the support of both strings and Path
objects in the Path
constructor a little more closely:
让我们更仔细地研究一下Path
构造函数中字符串和Path
对象的支持:
shark = Path(Path.home(), "ocean", "animals", Path("fish", "shark.txt"))
print(shark)
If we run this Python code, we’ll receive output similar to the following:
如果运行此Python代码,我们将收到类似于以下内容的输出:
Output
/Users/sammy/ocean/animals/fish/shark.txt
shark
is a Path
to a file that we constructed using both Path
objects (Path.home()
and Path("fish", "shark.txt")
) and strings ("ocean"
and "animals"
). The Path
constructor intelligently handles both types of objects and cleanly joins them using the appropriate operating system separator, in this case /
.
shark
是一个Path
到一个文件,我们使用这两种构建Path
(对象Path.home()
和Path("fish", "shark.txt")
和字符串( "ocean"
和"animals"
)。 Path
构造函数智能地处理这两种类型的对象,并使用适当的操作系统分隔符(在本例中为/
干净地将它们连接在一起。
访问文件属性 (Accessing File Attributes)
Now that we’ve learned how to construct Path
instances, let’s review how you can use those instances to access information about a file.
现在,我们已经学习了如何构造Path
实例,让我们回顾一下如何使用这些实例访问有关文件的信息。
We can use the name
and suffix
attributes to access file names and file suffixes:
我们可以使用name
和suffix
属性来访问文件名和文件后缀:
wave = Path("ocean", "wave.txt")
print(wave)
print(wave.name)
print(wave.suffix)
Running this code, we’ll receive output similar to the following:
运行此代码,我们将收到类似于以下内容的输出:
Output
/Users/sammy/ocean/wave.txt
wave.txt
.txt
This output shows that the name of the file at the end of our path is wave.txt
and the suffix of that file is .txt
.
此输出显示路径末尾的文件名为wave.txt
,该文件的后缀为.txt
。
Path
instances also offer the with_name
function that allow you to seamlessly create a new Path
object with a different name:
Path
实例还提供了with_name
函数,该函数使您可以无缝创建具有不同名称的新Path
对象:
wave = Path("ocean", "wave.txt")
tides = wave.with_name("tides.txt")
print(wave)
print(tides)
If we run this, we’ll receive output like the following:
如果运行此命令,我们将收到类似以下的输出:
ocean/wave.txt
ocean/tides.txt
The code first constructs a Path
instance that points to a file named wave.txt
. Then, we call the with_name
method on wave
to return a second Path
instance that points to a new file named tides.txt
. The ocean/
directory portion of the path remains unchanged, leaving the final path as ocean/tides.txt
该代码首先构造一个Path
实例,该实例指向名为wave.txt
的文件。 然后,我们调用with_name
的方法wave
返回第二个Path
是个实例的文件名为tides.txt
。 路径的ocean/
目录部分保持不变,最终路径保留为ocean/tides.txt
访问祖先 (Accessing Ancestors)
Sometimes it is useful to access directories that contain a given path. Let’s consider an example:
有时访问包含给定路径的目录很有用。 让我们考虑一个例子:
shark = Path("ocean", "animals", "fish", "shark.txt")
print(shark)
print(shark.parent)
If we run this code, we’ll receive output that looks like the following:
如果运行此代码,我们将收到类似于以下内容的输出:
Output
ocean/animals/fish/shark.txt
ocean/animals/fish
The parent
attribute on a Path
instance returns the most immediate ancestor of a given file path. In this case, it returns the directory that contains the shark.txt
file: ocean/animals/fish
.
Path
实例上的parent
属性返回给定文件路径的最直接祖先。 在这种情况下,它将返回包含shark.txt
文件的目录: ocean/animals/fish
。
We can access the parent
attribute multiple times in a row to traverse up the ancestry tree of a given file:
我们可以连续访问parent
属性多次以遍历给定文件的祖先树:
shark = Path("ocean", "animals", "fish", "shark.txt")
print(shark)
print(shark.parent.parent)
If we run this code, we’ll receive the following output:
如果运行此代码,我们将收到以下输出:
Output
ocean/animals/fish/shark.txt
ocean/animals
The output is similar to the earlier output, but now we’ve traversed yet another level higher by accessing .parent
a second time. Two directories up from shark.txt
is the ocean/animals
directory.
输出类似于先前的输出,但是现在我们通过第二次访问.parent
遍历了另一个更高的层次。 shark.txt
两个目录是ocean/animals
目录。
使用Glob列出文件 (Using Glob to List Files)
It’s also possible to use the Path
class to list files using the glob
method.
也可以使用Path
类通过glob
方法列出文件。
Let’s say we had a directory structure that looked like this:
假设我们有一个看起来像这样的目录结构:
└── ocean
├── animals
│ └── fish
│ └── shark.txt
├── tides.txt
└── wave.txt
An ocean
directory contains the files tides.txt
and wave.txt
. We have a file named shark.txt
nested under the ocean
directory, an animals
directory, and a fish
directory: ocean/animals/fish
.
ocean
目录包含文件tides.txt
和wave.txt
。 我们有一个名为shark.txt
的文件,嵌套在ocean
目录, animals
目录和fish
目录下: ocean/animals/fish
。
To list all the .txt
files in the ocean
directory, we could say:
要列出ocean
目录中的所有.txt
文件,我们可以说:
for txt_path in Path("ocean").glob("*.txt"):
print(txt_path)
This code would yield output like:
此代码将产生如下输出:
Output
ocean/wave.txt
ocean/tides.txt
The "*.txt"
glob pattern finds all files ending in .txt
. Since the code sample executes that glob in the ocean
directory, it returns the two .txt
files in the ocean
directory: wave.txt
and tides.txt
.
"*.txt"
全局模式可找到所有以.txt
结尾的文件。 由于代码示例执行该水珠在ocean
的目录,它返回两个.txt
的文件ocean
目录: wave.txt
和tides.txt
。
Note: If you would like to duplicate the outputs shown in this example, you’ll need to mimic the directory structure illustrated here on your computer.
注意:如果要复制此示例中显示的输出,则需要模拟计算机上此处所示的目录结构。
We can also use the glob
method recursively. To list all the .txt
files in the ocean
directory and all its subdirectories, we could say:
我们还可以递归使用glob
方法。 要列出ocean
目录及其所有子目录中的所有.txt
文件,我们可以说:
for txt_path in Path("ocean").glob("**/*.txt"):
print(txt_path)
If we run this code, we’d receive output like the following:
如果运行此代码,我们将收到如下输出:
Output
ocean/wave.txt
ocean/tides.txt
ocean/animals/fish/shark.txt
The **
part of the glob pattern will match this directory and all directories beneath it, recursively. So, not only do we have the wave.txt
and tides.txt
files in the output, but we also receive the shark.txt
file that was nested under ocean/animals/fish
.
全局模式的**
部分将递归匹配此目录及其下的所有目录。 因此,我们不仅在输出中包含wave.txt
和tides.txt
文件,而且还收到嵌套在ocean/animals/fish
下的shark.txt
文件。
计算相对路径 (Computing Relative Paths)
We can use the Path.relative_to
method to compute paths relative to one another. The relative_to
method is useful when, for example, you want to retrieve a portion of a long file path.
我们可以使用Path.relative_to
方法来计算相对于彼此的路径。 例如,当您想要检索长文件路径的一部分时, relative_to
方法很有用。
Consider the following code:
考虑以下代码:
shark = Path("ocean", "animals", "fish", "shark.txt")
below_ocean = shark.relative_to(Path("ocean"))
below_animals = shark.relative_to(Path("ocean", "animals"))
print(shark)
print(below_ocean)
print(below_animals)
If we run this, we’ll receive output like the following:
如果运行此命令,则将收到类似以下的输出:
Output
ocean/animals/fish/shark.txt
animals/fish/shark.txt
fish/shark.txt
The relative_to
method returns a new Path
object relative to the given argument. In our example, we compute the Path
to shark.txt
relative to the ocean
directory, and then relative to both the ocean
and animals
directories.
relative_to
方法返回相对于给定参数的新Path
对象。 在我们的示例中,我们相对于ocean
目录(然后相对于ocean
目录和animals
目录)计算shark.txt
的Path
。
If relative_to
can’t compute an answer because we give it an unrelated path, it raises a ValueError
:
如果relative_to
因为我们给它一个不相关的路径而无法计算答案,则会引发ValueError
:
shark = Path("ocean", "animals", "fish", "shark.txt")
shark.relative_to(Path("unrelated", "path"))
We’ll receive a ValueError
exception raised from this code that will be something like this:
我们将收到此代码引发的ValueError
异常,如下所示:
Output
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/Python3.8/pathlib.py", line 899, in relative_to
raise ValueError("{!r} does not start with {!r}"
ValueError: 'ocean/animals/fish/shark.txt' does not start with 'unrelated/path'
unrelated/path
is not a part of ocean/animals/fish/shark.txt
, so there’s no way for Python to compute a relative path for us.
unrelated/path
不是ocean/animals/fish/shark.txt
,因此Python无法为我们计算相对路径。
结论 (Conclusion)
The pathlib
module is a powerful part of the Python Standard Library that lets us manipulate filesystem paths quickly on any operating system. In this tutorial, we have learned to use some of pathlib
’s key utilities for accessing file attributes, listing files with glob patterns, and traversing parent files and directories.
pathlib
模块是Python标准库的强大功能,可让我们在任何操作系统上快速操作文件系统路径。 在本教程中,我们学习了使用pathlib
的一些关键实用程序来访问文件属性,列出具有glob模式的文件以及遍历父文件和目录。
The pathlib
module exposes additional classes and utilities that we did not cover in this tutorial. Now that you have a baseline, you can use the pathlib
module’s documentation to learn more about other available classes and utilities.
pathlib
模块公开了我们在本教程中未涵盖的其他类和实用程序。 有了基准后,就可以使用pathlib
模块的文档来了解有关其他可用类和实用程序的更多信息。
If you’re interested in using other Python libraries, check out the following tutorials:
如果您对使用其他Python库感兴趣,请查看以下教程: