回答

收藏

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

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

检查文件要写的目录是否存在。如果不存在,请使用 Python 创建目录最优雅的方法是什么?这是我试过的:
9 a" o- L/ T! m. \9 e
    import osfile_path = "/my/directory/filename.txt"directory = os.path.dirname(file_path)try:    os.stat(directory)except:    os.mkdir(directory)f = file(filename)
    4 y- g* P, D* t0 f. L! Y
不知何故,我错过了os.path.exists(感谢 kanja、Blair 和 Douglas)。这就是我现在所拥有的:
( m5 L6 i3 N4 `3 {
    def ensure_dir(file_path):    directory = os.path.dirname(file_path)    if not os.path.exists(directory):        os.makedirs(directory)
    * k( ^4 Z0 _2 C, y; O, X
是否有标志open()自动发生?$ d  M9 e8 O# R& w* }
                                                                  r/ i9 v8 l$ a6 I8 _
    解决方案:                                                                8 f; u7 z3 |3 t, v2 T
                                                                在 Python ≥ 3.5 上,使用pathlib.Path.mkdir:
7 M2 @% y. f- m. F& |
    from pathlib import PathPath("/my/directory").mkdir(parents=True,exist_ok=True); W# u; x$ p: E, i9 w  P7 c
旧版 Python,我看到两个质量好的答案,每个都有一个小缺陷,所以我会给出我的看法:
* v, H9 {: v+ ~4 K* C; R+ f尝试os.path.exists,并os.makedirs考虑创作。, R* q+ o5 ?0 Z/ J2 j1 }$ Q5 @2 |5 J3 G, Z
    import osif not os.path.exists(directory):    os.makedirs(directory)
    5 h4 n0 d% |0 t( d
如评论等地方所述,有竞争条件 - 如果在os.path.exists和os.makedirs在调用之间创建目录,os.makedirs并显示失败OSError. 不幸的是,一揽子捕获OSError而且继续不是万无一失的,因为它会忽略其他因素导致的目录创建失败,如权限不足、磁盘满等。9 e( s% R! I: A. s) R
捕获是一种选择OSError并检查嵌入的错误代码:
; \; Q! y& i8 T
    import os,errnotry:    os.makedirs(directory)except OSError as e:    if e.errno != errno.EEXIST:        raise; E+ T+ J6 O* J; x3 p+ p6 o0 ]
或者,可能有第二个os.path.exists,但假设另一个人在第一次检查后创建了目录,然后在第二次检查前删除它——我们仍然可能被愚弄。
! G/ l7 T- H3 Q: L5 m根据不同的应用程序,并发操作的风险可能大于或小于其他因素(如文件权限)。在选择实现之前,开发人员必须更多地了解正在开发的特定应用程序及其预期环境。) y! K  K- S: @$ t1 W
现代版Python 通过公开FileExistsError(在 3.3  中)…) u; c3 ^2 m( x! [3 s
    try:    os.makedirs("path/to/directory")except FileExistsError:    # directory already exists    pass
    . j) ~$ H) }0 S9 K; U* w) e
…并允许调用关键字参数os.makedirs``exist_ok(在 3.2  中)。
6 {  r9 B0 P6 Y! Z. ]* s% J
    os.makedirs("path/to/directory",exist_ok=True)  # succeeds even if directory exists.6 h. [% }: j- p9 \3 y3 Q
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则