如何创建一个不存在的目录?

检查文件将要写入的目录是否存在最优雅的方法是什么,如果不是,使用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.exists (感谢kanja,Blair和Douglas)。 这是我现在拥有的:

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

有没有“开放”的标志,这会自动发生?


我看到两个质量很好的答案,每个答案都有一个小缺陷,所以我会考虑一下:

尝试os.path.exists ,并考虑创建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.exists ,但假设另一个在第一次检查后创建目录,然后在第二个之前删除它 - 我们仍然可能被愚弄。

根据应用程序的不同,并发操作的危险可能比其他因素(如文件权限)带来的危险更大或更小。 在选择实现之前,开发人员必须更多地了解正在开发的特定应用程序及其预期环境。


Python 3.5+:

import pathlib
pathlib.Path('/my/directory').mkdir(parents=True, exist_ok=True) 

pathlib.Path.mkdir使用的pathlib.Path.mkdir递归创建目录,如果目录已经存在,则不会引发异常。 如果您不需要或不想要创建parents ,请跳过parents说法。

Python 3.2+:

使用pathlib

如果可以,请安装名为pathlib2的当前pathlib backport。 不要安装名为pathlib的旧的未保持的backport。 接下来,请参阅上面的Python 3.5+部分并使用它。

如果使用Python 3.4,即使它带有pathlib ,backport也是为了提供更新,更高级的mkdir实现。

使用os

import os
os.makedirs(path, exist_ok=True)

os.makedirs使用的os.makedirs递归创建目录,如果目录已经存在,不会引发异常。 它仅在使用Python 3.2+时具有可选的exist_ok参数,默认值为False 。 Python 2.x中不存在此参数,最高为2.7。 因此,与Python 2.7一样,不需要手动异常处理。

Python 2.7+:

使用pathlib

如果可以,请安装名为pathlib2的当前pathlib backport。 不要安装名为pathlib的旧的未保持的backport。 接下来,请参阅上面的Python 3.5+部分并使用它。

使用os

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创建嵌套目录,如果该目录已经存在, mkpath执行任何操作。 这适用于Python 2和Python 3。

import distutils.dir_util
distutils.dir_util.mkpath(path)

根据Bug 10948,这种替代方案的一个严重限制是它对于给定的路径在每个Python进程中仅工作一次。 换句话说,如果你用它创建一个目录,然后从Python内部或外部删除目录,然后再次使用mkpath重新创建相同的目录, mkpath将简单地静静地使用它以前创建目录的无效缓存信息,以及实际上不会再次制作目录。 相比之下, os.makedirs不依赖任何这样的缓存。 对于某些应用程序,此限制可能没有问题。


关于目录的模式,如果您关心它,请参阅文档。


使用除errno模块之外的尝试以及正确的错误代码摆脱竞争条件并且是跨平台的:

import os
import errno

def make_sure_path_exists(path):
    try:
        os.makedirs(path)
    except OSError as exception:
        if exception.errno != errno.EEXIST:
            raise

换句话说,我们尝试创建目录,但是如果它们已经存在,我们会忽略该错误。 另一方面,报告任何其他错误。 例如,如果您事先创建errno.EACCES '并从中删除所有权限,则会收到errno.EACCES (Permission denied,error 13)引发的OSError

链接地址: http://www.djcxy.com/p/171.html

上一篇: How can I create a directory if it does not exist?

下一篇: What does "yield break;" do in C#?