判断文件要写入的目录是否存在,如果不存在,使用Python创建目录,最优雅的方法是什么?以下是我try 过的:

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)

有没有一个open()的旗帜,让这件事自动发生?

推荐答案

关于Python≥ 3.5,使用pathlib.Path.mkdir:

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

对于较旧版本的Python,我看到了两个很好的答案,每个答案都有一个小缺陷,因此我将给出我的看法:

try os.path.exists,并考虑os.makedirs的创作.

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

As noted in comments and elsewhere, there's a race condition – if the directory is created between the os.path.exists and the os.makedirs calls, the os.makedirs will fail with an OSError. Unfortunately, blanket-catching OSError and continuing is not foolproof, as it will ignore a failure to create the directory due to other factors, such as insufficient permissions, full disk, etc.

一种选择是捕获OSError并判断嵌入的错误代码(请参见Is there a cross-platform way of getting information from Python’s OSError):

import os, errno

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

Alternatively, there could be a second os.path.exists, but suppose another created the directory after the first check, then removed it before the second one – we could still be fooled.

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

Python的现代版本大大改进了这段代码,它们都是通过公开FileExistsError(在3.3+中)和...

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

.并允许a keyword argument to os.makedirs called exist_ok(3.2+).

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

Python相关问答推荐

如何计算Pandas 数据框中单元格内的行数,这些行数不是空行

将多列拆分为多列,Pandas

使用 make_axes_locatable 时如何删除 matplotlib 子图中的填充

如何使用相同的方法按不同属性快速排序对象列表?

如何重构此代码片段以提高效率?

组合数组的相似元素

如何根据 Pandas 中的索引级别设置行值?

Python集解包和模式匹配

实现 tensorflow 对象检测模型时出错

二分搜索:没有得到非常大的值的上限和下限

在 Python3 中将非整数成员值添加到 IntEnum

数据集中值的 Python 总和

如何将postman 中的 JSON 格式数据发送到具有另一个模型的外键的 django 模型?

如何向输入字典添加别名?

反转Pandas 中的行值

Python:如何将列表中以某个字母开头的元素复制到新列表中或从列表中删除不以字母开头的元素

Python:元组和单个浮点数的高效展开/展平列表

带有 APIRouter 插件系统的 FastAPI 无法正常工作

获取目录中所有文件名的列表及其原始文件夹顺序

将 Python 字典键入为 Dict[key[T], value[K]] 其中 T 和 K 受到限制