如何在 Python 中安全地创建嵌套目录? [英] How can I safely create a nested directory in Python?

查看:80
本文介绍了如何在 Python 中安全地创建嵌套目录?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

检查文件要写入的目录是否存在,如果不存在,使用 Python 创建目录的最优雅的方法是什么?这是我尝试过的:

What is the most elegant way to check if the directory a file is going to be written to exists, and if not, create the directory using Python? Here is what I tried:

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).这就是我现在所拥有的:

Somehow, I missed os.path.exists (thanks kanja, Blair, and Douglas). This is what I have now:

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

是否有一个打开"标志,可以自动发生这种情况?

Is there a flag for "open", that makes this happen automatically?

推荐答案

在 Python ≥ 3.5 上,使用 pathlib.Path.mkdir:

On Python ≥ 3.5, use pathlib.Path.mkdir:

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

对于旧版本的 Python,我看到两个质量很好的答案,每个都有一个小缺陷,所以我会给出我的看法:

For older versions of Python, I see two answers with good qualities, each with a small flaw, so I will give my take on it:

尝试 os.path.exists,并考虑 os.makedirs 用于创作.

Try os.path.exists, and consider os.makedirs for the creation.

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

正如评论和其他地方所指出的,存在竞争条件——如果目录是在 os.path.existsos.makedirs 调用之间创建的,os.makedirs 将失败并返回一个 操作系统错误.不幸的是,一揽子捕获OSError并继续并不是万无一失的,因为它会忽略由于其他因素导致的目录创建失败,例如权限不足、磁盘已满等.

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 并检查嵌入的错误代码(请参阅 是否有跨平台的方式从 Python 的 OSError 中获取信息):

One option would be to trap the OSError and examine the embedded error code (see 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

或者,可能还有第二个 os.path.exists,但假设另一个人在第一次检查后创建了该目录,然后在第二次检查之前将其删除 –我们仍然可能被愚弄.

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.

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

Depending on the application, the danger of concurrent operations may be more or less than the danger posed by other factors such as file permissions. The developer would have to know more about the particular application being developed and its expected environment before choosing an implementation.

现代版本的 Python 通过公开 <代码>FileExistsError(在 3.3+ 中)...

Modern versions of Python improve this code quite a bit, both by exposing FileExistsError (in 3.3+)...

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

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

...and by allowing a keyword argument to os.makedirs called exist_ok (in 3.2+).

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

这篇关于如何在 Python 中安全地创建嵌套目录?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆