回答

收藏

如何安全地创建嵌套目录?

技术问答 技术问答 553 人阅读 | 0 人回复 | 2023-09-11

检查文件要写的目录是否存在。如果不存在,请使用 Python 创建目录最优雅的方法是什么?这是我试过的:
- L& `+ I9 u/ G/ b1 O& p
    import osfile_path = "/my/directory/filename.txt"directory = os.path.dirname(file_path)try:    os.stat(directory)except:    os.mkdir(directory)f = file(filename)
    * P! K7 @. S& z5 V2 G
不知何故,我错过了os.path.exists(感谢 kanja、Blair 和 Douglas)。这就是我现在所拥有的:* Y8 D4 K0 ^# D1 O% @4 G% A4 o8 }
    def ensure_dir(file_path):    directory = os.path.dirname(file_path)    if not os.path.exists(directory):        os.makedirs(directory)& \9 I& @! O4 g( x+ e1 u
是否有标志open()自动发生?
1 j4 m, Z7 \& B# b: ~3 |1 s5 y                                                               
+ K1 Z  u; K5 H3 I4 P$ m' ?3 K    解决方案:                                                                7 R+ v& y' W5 U2 k* n
                                                                在 Python ≥ 3.5 上,使用pathlib.Path.mkdir:
0 r7 x* Y8 y, ^2 x0 N
    from pathlib import PathPath("/my/directory").mkdir(parents=True,exist_ok=True)
    $ E' U+ o& k3 }& F" c
旧版 Python,我看到两个质量好的答案,每个都有一个小缺陷,所以我会给出我的看法:
6 w+ H2 H4 N& F尝试os.path.exists,并os.makedirs考虑创作。7 a" }, F# U( C! {# \) s: T' A
    import osif not os.path.exists(directory):    os.makedirs(directory)7 B/ D5 j, b  F( k3 d; q3 i
如评论等地方所述,有竞争条件 - 如果在os.path.exists和os.makedirs在调用之间创建目录,os.makedirs并显示失败OSError. 不幸的是,一揽子捕获OSError而且继续不是万无一失的,因为它会忽略其他因素导致的目录创建失败,如权限不足、磁盘满等。) R* m% X* l- o; ^# Z) I
捕获是一种选择OSError并检查嵌入的错误代码:
# i0 v5 l5 W# l; M
    import os,errnotry:    os.makedirs(directory)except OSError as e:    if e.errno != errno.EEXIST:        raise# [5 k* L& `7 R8 g
或者,可能有第二个os.path.exists,但假设另一个人在第一次检查后创建了目录,然后在第二次检查前删除它——我们仍然可能被愚弄。2 y' |" D4 w- o% f  t+ N+ _, I
根据不同的应用程序,并发操作的风险可能大于或小于其他因素(如文件权限)。在选择实现之前,开发人员必须更多地了解正在开发的特定应用程序及其预期环境。+ u% P& u0 U+ O4 o9 i
现代版Python 通过公开FileExistsError(在 3.3  中)…3 _7 u" s$ v& U3 U( s# D6 X4 S
    try:    os.makedirs("path/to/directory")except FileExistsError:    # directory already exists    pass' V& X5 Q* h5 D- r- B
…并允许调用关键字参数os.makedirs``exist_ok(在 3.2  中)。) O3 o8 Z) f8 N6 e  |, T, ?
    os.makedirs("path/to/directory",exist_ok=True)  # succeeds even if directory exists.& y( [) a! W. t1 C1 _- j0 }  |
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则