用Python检查文件或文件夹是否存在的7种方法
Python标准库包含了开发人员解决问题所需的大部分功能。在本教程中,您将学习使用内置模块的不同方法来检查文件或目录是否存在。
检查文件或目录是否在正确的位置是任何命令行程序的关键。如果在执行时特定文件不在指定位置,您的程序可能变得无用。
在今天的教程中,您将学习一些快速检查文件或文件夹是否存在的方法。
开始之前
在执行下面的任何命令之前,请确保您的系统已安装Python 3。打开终端并输入以下命令:
python --version
# 我的结果是Python 3.9.5
如果您得到的是2.x版本,您将需要使用“python3”命令。如果您尚未安装Python 3,请参阅我们的链接1。
我们将在本教程中使用一些测试文件,请确保创建以下文件:
touch testfile.txt
mkdir testdirectory/
touch testdirectory/otherfile.txt
上述命令创建了一个用于演示的文件、一个测试目录以及测试目录内的另一个文件。这些文件可以是空的,因为我们不需要读取它们的内容。
注意:如果您使用的是Windows,请使用图形文件管理器设置该文件的简单文件结构。
最后,我们将使用链接2作为我们的交互式Python shell,它提供了一个漂亮的界面供我们使用。这只是一个便利,因此并不是必需的。
pip install ipython
完成后,只需键入ipython,即可访问一个漂亮的Python shell。
现在您已经准备好了,让我们深入了解在Python中检查文件夹或文件是否存在的方法。
尝试、打开和异常处理
这是最直接的选项。如果尝试打开一个不存在的文件,Python将引发一个文件未找到的异常。
In [1]: open('im-not-here.txt')
---------------------------------------------------------------------------
FileNotFoundError: [Errno 2] No such file or directory: 'im-not-here.txt'
我们可以利用这一点,在找不到所需文件时处理异常。
In [2]: try:
...: file = open('im-not-here.txt')
...: print(file) # 文件处理器
...: file.close()
...: except FileNotFoundError:
...: print('抱歉,我们要找的文件不存在')
...: exit()
...:
抱歉,我们要找的文件不存在
在上面的代码中,如果文件不存在,我们打印一个自定义消息并停止程序的执行。
请注意,exit()函数仅在引发异常时才执行。让我们看看当我们要查找的文件实际存在时会发生什么。
In [2]: try:
...: file = open('testfile.txt')
...: print(file) # 文件处理器
...: file.close()
...: except FileNotFoundError:
...: print('抱歉,我们要找的文件不存在')
...: exit()
...:
请注意,在打开文件后我们立即关闭了它。根据链接4的建议,这被认为是一种良好的做法。
调用
file.write()
而不使用with
关键字或调用file.close()
可能会导致file.write()
的参数没有完全写入磁盘,即使程序成功退出。
即使我们不写入文件,强烈建议关闭文件,因为这可能导致multiple performance problems。
如果我们不想自己关闭文件,我们可以使用with 上下文管理器。它可以准确地分配和释放资源,因此我们不需要关闭文件。
In [3]: try:
...: with open('testfile.txt') as file:
...: print(file)
...: # No need to close the file
...: except FileNotFoundError:
...: print('抱歉,我们正在寻找的文件不存在')
...: exit()
...:
...:
这种方法在写入文件时非常有用,但如果我们只想检查文件是否存在,则效率低下。让我们深入了解其他选项来实现此目的。
os.path.exists()
链接_6提供了与操作系统进行交互的多个函数。要检查文件或文件夹是否存在,我们可以使用path.exists()函数,该函数接受文件或目录的路径作为参数,并根据路径的存在与否返回一个布尔值。
注意:路径是文件系统中文件或目录的唯一位置。
在Python中,os.path子模块包含专门用于处理文件路径的函数。所有这些函数都将路径参数作为字符串或字节接受,并且您可以选择使用绝对路径进行操作,例如:
/home/daniel/.bashrc
或者使用相对路径,取决于您运行脚本的目录:
.bashrc
# 在我的主文件夹中运行脚本
以下是在我的测试文件所在目录中运行的多个使用os.path.exists()函数的示例:
In [1]: import os
In [2]: os.path.exists('testfile.txt')
Out[2]: True
In [3]: os.path.exists('testdirectory')
Out[3]: True
In [4]: os.path.exists('hey-i-dont-exist')
Out[4]: False
如您所见,使用testfile.txt文件和testdirectory文件夹进行测试时,它返回True,当文件不存在时返回False。
os.path.isfile()
如果您只想证明文件的存在(而不是目录),则可以调用os.path.isfile()函数。
In [1]: import os
In [2]: os.path.isfile('testfile.txt')
Out[2]: True
In [3]: os.path.isfile('testdirectory/')
Out[3]: False
In [4]: os.path.isfile('i-dont-even-exist')
Out[4]: False
In [5]: os.path.isfile('testdirectory/otherfile.txt')
Out[5]: True
注意:在UNIX中,所有目录以正斜杠(/)结尾,而在Windows中我们使用反斜杠()。
在上面的代码中,isfile()函数在两个情况下返回False,让我们看看为什么:
testdirectory/
是一个目录,因此不被视为文件。这并非完全正确,因为在Linux中,everything is a file descriptor,但是Python为了方便起见对待目录有所不同(如果你尝试打开一个目录,你会得到一个IsADirectoryError)i-dont-even-exist
指向一个讽刺的不存在的文件
os.path.isdir()
如果你想检查一个目录是否在正确的位置,你需要使用os.path.isdir()函数,它只在给定的路径指向一个目录时返回True。
In [1]: import os
In [2]: os.path.isdir('testfile.txt')
Out[2]: False
In [3]: os.path.isdir('testdirectory')
Out[3]: True
In [4]: os.path.isdir('anotherfile.txt')
Out[4]: False
请注意,上面的示例返回False,即使路径指向一个存在的文件。
Glob
glob模块提供了与Unix shell-like patterns一起使用的函数(因此在Windows上无法正常工作)。要检查文件是否与当前目录中的模式匹配,可以使用glob.glob()函数。
In [1]: import glob
In [2]: glob.glob('testfile.txt')
Out[2]: ['testfile.txt']
In [3]: glob.glob('testdirectory')
Out[3]: ['testdirectory']
在上面的代码中,传递给glob函数的模式是一个正常的字符串,表示测试文件和目录的路径。由于这两个路径都存在,函数将返回一个包含匹配路径名的列表。
注意:如果模式不匹配,你将得到一个空列表。
考虑到我们可以将模式传递给glob函数,为什么不测试一下它的一些主要优点呢?
下面的代码分别获取所有具有扩展名.txt和.py的文件路径:
In [4]: glob.glob('*.txt')
Out[4]: ['testfile.txt']
In [5]: glob.glob('*.py')
Out[5]:
['pathlib-exists.py',
'list-dir.py',
'glob-file.py',
'open-except.py',
'subprocess-test.py',
'isfile.py',
'exists.py',
'isdir.py']
使用Path类
Path class是处理路径的最佳方式之一,因为它为我们提供了一个清晰的界面来处理文件路径作为对象。
这个库的优点之一是Path实例有所有你需要的用于获取有关特定路径信息的方法。这包括与前面的选项类似的功能。
注意:您需要Python 3.4或更高版本才能使用pathlib库
你将使用的Path方法:
检查路径是否存在
In [1]: from pathlib import Path
In [2]: Path('testfile.txt').exists()
Out[2]: True
In [3]: Path('im-not-here.txt').exists()
Out[3]: False
In [4]: Path('testdirectory').exists()
Out[4]: True
与os.path.exists()的工作方式相同。
检查路径是否指向文件
In [5]: Path('testfile.txt').is_file()
Out[5]: True
In [6]: Path('testdirectory').is_file()
Out[6]: False
等同于os.path.isfile()。
检查路径是否指向目录
In [7]: Path('testfile.txt').is_dir()
Out[7]: False
In [8]: Path('testdirectory').is_dir()
Out[8]: True
对应于os.path.isdir()。
子进程
如果你是一个subprocess module爱好者,你需要了解这个选项。你可以使用test command来确定文件或文件夹是否存在。
注意:test命令只在Unix中有效。
以下测试标志将完成工作:
- 测试 -e:检查路径是否存在
- 测试 -f:检查文件是否存在
- 测试-d:检查文件夹是否存在
如果您想了解更多测试标志,可以运行以下命令阅读手册:
man test
使用subprocess检查路径:
下面的代码通过比较子进程的返回代码是否为0来确定路径是否存在。
请记住,在Linux中,如果进程运行成功,它会返回零,如果没有成功,则返回其他代码。
In [1]: from subprocess import run
In [2]: run(['test', '-e', 'testfile.txt']).returncode == 0
Out[2]: True
In [3]: run(['test', '-e', 'im-not-here.txt']).returncode == 0
Out[3]: False
在第一个语句中,我们导入了subprocess模块,然后使用run函数并获取其返回代码。
使用subprocess验证文件的存在性
In [4]: run(['test', '-f', 'testfile.txt']).returncode == 0
Out[4]: True
In [5]: run(['test', '-f', 'testdirectory']).returncode == 0
Out[5]: False
使用subprocess检查目录:
In [6]: run(['test', '-d', 'testfile.txt']).returncode == 0
Out[6]: False
In [7]: run(['test', '-d', 'testdirectory']).returncode == 0
Out[7]: True
不推荐使用此选项,因为它会消耗更多资源,而且我们从中没有获得任何好处。
总结
Python是最常用的用于与操作系统交互以自动化过程的编程语言之一。您可以使用Python检查文件或文件夹是否存在。
最直接的方法有:
- 立即打开和处理文件异常
- 使用os.path或pathlib模块的exists()函数。
在本教程中,您学到了:
- 如何打开文件并处理不存在的异常
- 路径的含义
- os.path子模块提供的3个不同函数来检查文件或文件夹的存在性
- Unix使用斜杠(/),而Windows使用反斜杠()