如何安全地创建嵌套目录?
如何检查要写入文件的目录是否存在,如果没有,请使用Python创建目录?
如何检查要写入文件的目录是否存在,如果没有,请使用Python创建目录?
在 Python ≥ 3.5 上,使用 pathlib。Path.mkdir
:
from pathlib import Path
Path("/my/directory").mkdir(parents=True, exist_ok=True)
对于旧版本的Python,我看到两个具有良好品质的答案,每个答案都有一个小缺陷,所以我将给出我的看法:
尝试os.path.exists
,并考虑os.makedirs
进行创建。
import os
if not os.path.exists(directory):
os.makedirs(directory)
如注释和其他地方所述,存在争用条件 - 如果在 和 调用之间创建目录,则 将失败并显示 .不幸的是,一揽子捕获和继续并不是万无一失的,因为它会忽略由于其他因素(例如权限不足,完整磁盘等)而导致目录创建失败的情况。os.path.exists
os.makedirs
os.makedirs
OSError
OSError
一种选择是捕获并检查嵌入的错误代码(请参阅是否有跨平台的方式从Python的OSError获取信息):OSError
import os, errno
try:
os.makedirs(directory)
except OSError as e:
if e.errno != errno.EEXIST:
raise
或者,可能会有第二个,但假设另一个在第一次检查后创建了目录,然后在第二次检查之前将其删除 - 我们仍然可能被愚弄。os.path.exists
根据应用程序的不同,并发操作的危险可能大于或小于其他因素(如文件权限)带来的危险。在选择实现之前,开发人员必须了解有关正在开发的特定应用程序及其预期环境的更多信息。
Python的现代版本通过公开FileExistsError
(在3.3 +中)来改进此代码...
try:
os.makedirs("path/to/directory")
except FileExistsError:
# directory already exists
pass
...并允许一个名为exist_ok(在3.2+中)的os.makedirs
的关键字参数。
os.makedirs("path/to/directory", exist_ok=True) # succeeds even if directory exists.
import pathlib
pathlib.Path('/my/directory').mkdir(parents=True, exist_ok=True)
pathlib.上面使用的 Path.mkdir
以递归方式创建目录,如果该目录已存在,则不会引发异常。如果您不需要或不希望创建父级,请跳过该参数。parents
使用 pathlib
:
如果可以,请安装名为 pathlib2
的当前向后移植。不要安装名为 pathlib
的较旧的未维护的向后移植。接下来,参考上面的Python 3.5 +部分并使用它。pathlib
如果使用Python 3.4,即使它附带了,它也缺少有用的选项。向后移植旨在提供更新和更高级的实现,其中包括此缺少的选项。pathlib
exist_ok
mkdir
使用操作系统
:
import os
os.makedirs(path, exist_ok=True)
上面使用的 os.makedirs
递归创建目录,如果目录已存在,则不会引发异常。仅当使用 Python 3.2+ 时,它才具有可选参数,默认值为 。这个参数在Python 2.x到2.7中不存在。因此,不需要像Python 2.7那样手动处理异常。exist_ok
False
使用 pathlib
:
如果可以,请安装名为 pathlib2
的当前向后移植。不要安装名为 pathlib
的较旧的未维护的向后移植。接下来,参考上面的Python 3.5 +部分并使用它。pathlib
使用操作系统
:
import os
try:
os.makedirs(path)
except OSError:
if not os.path.isdir(path):
raise
虽然朴素的解决方案可能首先使用os.path.isdir
,然后是os.makedirs
,但上面的解决方案颠倒了这两个操作的顺序。这样,它可以防止与创建目录的重复尝试有关的常见争用条件,还可以消除目录文件中的歧义。
请注意,捕获异常和使用是有限的,因为 ,即 为文件和目录都引发。简单地检查目录是否存在更可靠。errno
OSError: [Errno 17] File exists
errno.EEXIST
mkpath
创建嵌套目录,如果该目录已存在,则不执行任何操作。这适用于Python 2和3。
import distutils.dir_util
distutils.dir_util.mkpath(path)
根据 Bug 10948,此替代方案的严重限制是,对于给定路径,每个 python 进程只能工作一次。换句话说,如果你用它来创建一个目录,然后从Python内部或外部删除该目录,然后再次使用重新创建同一目录,将简单地静默地使用其先前创建该目录的无效缓存信息,并且实际上不会再次创建该目录。相反,不依赖于任何此类缓存。对于某些应用程序,此限制可能没问题。mkpath
mkpath
os.makedirs
关于目录的模式,如果您关心它,请参阅文档。