欢迎来到雲闪世界。使用文件系统是那些乍看起来微不足道的任务之一,但即使是经验丰富的开发人员也很容易措手不及。我首先承认——我犯过不少错误。我遇到的最常见的反模式之一是在 Python 中将文件路径表示为字符串。
现在是时候重新考虑这种方法了。
在今天的文章中,我们将探讨为什么使用字符串(甚至是os
模块)作为文件路径会导致灾难。我们将深入研究最佳实践,并了解该pathlib
包如何帮助您编写更干净、更易于维护的代码。
为什么使用字符串作为路径不是一个好主意
如果您曾经从事过需要在不同操作系统上运行的项目,那么您就会知道处理路径的痛苦。不同的系统有不同的表示路径的方式。基于 Unix 的系统(如 Linux 和 macOS)使用正斜杠/
,而 Windows 使用反斜杠\
。这是一个小细节,但如果您不小心,可能会导致大麻烦。
# Unix (例如 Linux、OSX 等)
/home/this/is/a/path/to/a/directory
# Windows
C:\home\this\is\a\path\to\a\directory
我曾经花了几个小时调试一个脚本,这个脚本在我的 Mac 上运行完美,但当同事在 Windows 上运行它时,它就完全崩溃了。问题是什么?当然是文件路径。我将路径硬编码为字符串,假设它们在任何系统上的行为都相同。
这里的问题在于代码的可移植性。如果您使用字符串来表示路径,则需要编写条件逻辑来处理不同的操作系统。这不仅会使您的代码变得混乱,而且还会带来不必要的复杂性。
# 这是一种不好的做法
import platform
if platform.system() == 'Windows' :
filepath = 'C:\home\this\is\a\path\to\a\directory'
else : # 例如 OSX 为 'Darwin' 或 'Linux'
最糟糕的部分是什么?事情还不止于此。假设您需要连接两个路径。使用普通字符串连接可能会导致无效路径,尤其是当其中一个字符串末尾包含斜杠时。
相信我,我曾经经历过。
path_1 = '/this/is/a/path/'
path_2 = '/another/path'
# filepath = '/this/is/a/path//another/path'
filepath = path_1 + path_2
为什么 OS 模块不是解决方案
此时,有些人可能会想,“但是模块怎么办os
?”是的,使用os.path.join()
可以帮助您避免字符串连接的一些陷阱。但是,它远非完美的解决方案。
导入操作系统
path_1 = '/this/is/a/path/'
path_2 = '/another/path'
# filepath = '/another/path'
filepath = os.path.join(path_1, path_2)
虽然这避免了双斜杠的问题,但os
模块中的路径仍然只是字符串。这意味着您仍然需要处理字符串操作的所有限制和复杂性。需要提取父目录吗?想要检查文件是否存在?您将编写大量额外的代码来完成这些基本任务。
在我早期使用 Python 的时候,我非常依赖os
模块,认为它是路径操作的首选解决方案。但随着我的项目变得越来越复杂,与路径相关的错误也越来越多。
Pathlib 来救援!
这就是 的作用pathlib
所在。它是 Python 标准库的一部分,旨在让文件系统路径操作变得轻而易举。 的妙处pathlib
在于它能够将路径表示为对象 — 用于计算操作的纯路径和用于 I/O 操作的具体路径。
Pathlib 将路径表示为对象 — 来源:Python 文档(根据PSF 许可证授权)
作为示例,让我们考虑以下简单构建Path
使用Pathlib
库的代码块:
导入pathlib
path = pathlib.Path( 'folder' )/ 'subfolder' / 'another_subfolder'
打印(路径)
打印(类型(路径))
该代码的输出将根据操作系统而有所不同:
- 在 Unix 系统(Linux 或 macOS)上:
# 在 Unix 系统(例如 Linux 或 OSX)上运行时的输出
folder/subfolder/another_subfolder
<class 'pathlib.PosixPath' >
- 在 Windows 上
# 在 Windows 系统上运行的输出
folder\subfolder\another_subfolder
<class 'pathlib.WindowsPath' >
这种基于您运行的操作系统自动处理路径的功能将彻底改变游戏规则。而且它的好处还不止于此。
是什么让 Pathlib 如此强大?
在处理 Python 中的文件路径时,pathlib
它提供了一系列功能,不仅仅是修复字符串和模块的缺点。以下是它成为最佳工具的os
一些关键原因。pathlib
- 处理当前工作目录 (cwd)
无需再担心您的脚本是否会在 Windows 还是 Unix 上运行。Pathlib
它会为您处理好一切。
从pathlib导入Path
打印(Path.cwd())
# 在 Unix 上:PosixPath(/Users/gmyrianthous/test)
# 在 Windows 上:WindowsPath(C:\Users\gmyrianthous\test)
2. 以编程方式创建新目录
从pathlib导入Path
Path( 'new_directory' ).mkdir()
如果新建的目录已经存在,上述代码片段将会失败,如果想忽略此失败,可以在调用mkdir()
方法时指定相应的参数;
路径('new_directory').mkdir(exist_ok = True)
3. 检查文件是否存在
为了检查文件系统上是否存在特定文件,您首先必须构造一个,然后对路径对象Path
使用方法:exists()
从pathlib导入Path
file = Path( 'my_directory' ) /'data.txt '
打印(file.exists())
4. 列出目录的内容
要列出目录的内容,您可以调用iterdir()
以下命令返回一个迭代器:
从pathlib导入Path
filepath = Path( 'folder' )/ 'subfolder'
content = filepath.iterdir()
如果预计文件路径包含大量路径和文件,那么我建议您逐个迭代器内的文件,以避免将所有内容加载到内存中。
或者,如果您预期的内容量相对较少,您可以直接将迭代器转换为列表:
从pathlib导入路径
filepath = Path( 'folder' )/ 'subfolder'
content = list (filepath.iterdir())
最后的想法
在处理文件路径操作等看似简单的任务时,很容易忽视最佳实践。我知道我就是这样的。但随着项目的发展,这些“小”事情可能会成为主要的痛点。花时间学习和使用这样的工具pathlib
从长远来看会有回报,让你免于头痛和潜在的错误。
因此,如果您仍在使用字符串来表示 Python 中的路径,那么是时候进行切换了。感谢关注雲闪世界。(Aws解决方案架构师vs开发人员&GCP解决方案架构师vs开发人员)