回答

收藏

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

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

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

本版积分规则