我怎样才能安全地创建一个嵌套目录?

什么是最优雅的方法来检查一个文件要写入的目录是否存在,如果不存在,就用Python创建这个目录?以下是我所尝试的。

import os

file_path = "/my/directory/filename.txt"
directory = os.path.dirname(file_path)

try:
    os.stat(directory)
except:
    os.mkdir(directory)       

f = file(filename)

不知怎的,我错过了os.path.existence(感谢kanja、Blair和Douglas)。这就是我现在的情况。

def ensure_dir(file_path):
    directory = os.path.dirname(file_path)
    if not os.path.exists(directory):
        os.makedirs(directory)

是否有一个"open"的标志,使之自动发生?

解决办法

我看到两个答案都有很好的品质,每个都有一个小缺陷,所以我就说说我的看法。

尝试os.path.existence,并考虑os.makedirs进行创建。

import os
if not os.path.exists(directory):
    os.makedirs(directory)

正如评论和其他地方所指出的,有一个竞赛条件–如果目录是在os.path.existsos.makedirs调用之间创建的,os.makedirs将以OSError失败。不幸的是,一揽子捕获 "OSError "并继续下去并不是万无一失的,因为它将忽略由于其他因素导致的目录创建失败,如权限不足、磁盘已满等。

一种选择是捕获 "OSError "并检查嵌入的错误代码 (见 是否有一种跨平台的方法从Python的OSError中获取信息)。

import os, errno

try:
    os.makedirs(directory)
except OSError as e:
    if e.errno != errno.EEXIST:
        raise

另外,可能有第二个os.path.existence,但假设另一个人在第一次检查后创建了目录,然后在第二次检查前删除了它–我们还是可能被骗。

根据不同的应用,并发操作的危险可能多于或少于其他因素造成的危险,如文件权限。开发者在选择实现方式之前,必须更多地了解正在开发的特定应用程序及其预期环境。

现代版本的Python对这段代码进行了相当大的改进,既暴露了FileExistsError(在3.3以上)...

try:
    os.makedirs("path/to/directory")
except FileExistsError:
    # directory already exists
    pass

...并允许 os.makedirs 一个名为 exist_ok 的关键字参数 (在 3.2+ 中)。

os.makedirs("path/to/directory", exist_ok=True)  # succeeds even if directory exists.
评论(8)

检查 os.makedirs。 (它确保完整的路径存在。) 为了处理目录可能存在的事实,捕获OSError。 (如果exist_okFalse(默认),如果目标目录已经存在,就会产生OSError)。

import os
try:
    os.makedirs('./path/to/somewhere')
except OSError:
    pass
评论(3)

试试os.path.existence函数

if not os.path.exists(dir):
    os.mkdir(dir)
评论(3)