python文件不存在时创建文件_pyton-如何创建一个不存在的目录?

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

importos

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,布莱尔和道格拉斯)。这是我现在拥有的:

defensure_dir(file_path):directory=os.path.dirname(file_path)

if notos.path.exists(directory):os.makedirs(directory)

有没有“开放”的标志,这会自动发生?

答案

我看到两个质量很好的答案,每个答案都有一个小缺陷,所以我会考虑一下:

importosif notos.path.exists(directory):os.makedirs(directory)

正如评论和其他地方所指出的那样,竞争条件 – 如果目录是在创建os.path.exists和os.makedirs调用之间创建的,os.makedirs则会失败并显示一个OSError。不幸的是,一揽子捕捉OSError和继续并不是万无一失的,因为它会忽略由于其他因素造成的目录失败,如权限不足,磁盘满等。

一种选择是捕获OSError和检查嵌入的错误代码(请参阅从Python的OSError获取信息是否有跨平台的方式):

importos,errnotry:os.makedirs(directory)

except OSError ase:

ife.errno!=errno.EEXIST:

raise

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

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

Python 3.5+:

importpathlib

pathlib.Path('/my/directory').mkdir(parents=True,exist_ok=True)

pathlib.Path.mkdir如上面所使用的那样递归地创建目录,并且如果该目录已经存在则不会引发异常。如果您不需要或不想创建父母,请跳过该parents论点。

Python 3.2+:

使用pathlib:

如果可以,请安装指定的当前pathlibbackport pathlib2。不要安装旧的未维护的backport pathlib。接下来,请参阅上面的Python 3.5+部分并使用它。

如果使用Python 3.4,即使它附带了pathlib,backport也是为了提供更新,更高级的实现mkdir。

使用os:

importos

os.makedirs(path,exist_ok=True)

os.makedirs如上面所使用的那样递归地创建目录,并且如果该目录已经存在则不会引发异常。它exist_ok仅在使用Python 3.2+时具有可选参数,默认值为False。Python 2.x中不存在此参数,最高为2.7。因此,与Python 2.7一样,不需要手动异常处理。

Python 2.7+:

使用pathlib:

如果可以,请安装指定的当前pathlibbackport pathlib2。不要安装旧的未维护的backport pathlib。接下来,请参阅上面的Python 3.5+部分并使用它。

使用os:

importostry:os.makedirs(path)

except OSError:

if notos.path.isdir(path):

raise

而幼稚溶液可首先使用os.path.isdir,接着os.makedirs,在溶液上方反转两个操作的顺序。这样做可以防止共同的竞争条件与创建目录时的重复尝试有关,也可以消除目录中的文件歧义。

请注意,捕获异常并使用errno的用处有限,因为OSError: [Errno 17] File exists即errno.EEXIST针对文件和目录引发异常。简单地检查目录是否存在更为可靠。

替代方案:

mkpath创建嵌套目录,如果该目录已经存在,则不执行任何操作。这适用于Python 2和Python 3。

importdistutils.dir_util

distutils.dir_util.mkpath(path)

根据Bug 10948,这种替代方案的一个严重限制是它对于给定的路径在每个Python进程中仅工作一次。换句话说,如果你使用它来创建一个目录,那么从Python内部或外部删除目录,然后mkpath再次使用来重新创建相同的目录,mkpath将简单地静静地使用其以前创建目录的无效缓存信息,而不会实际上再次制作目录。相比之下,os.makedirs不依赖于任何这样的缓存。对于某些应用程序,此限制可能没有问题。

使用除errno模块之外的尝试以及正确的错误代码摆脱竞争条件并且是跨平台的:

importosimporterrnodefmake_sure_path_exists(path):

try:os.makedirs(path)

except OSError asexception:

ifexception.errno!=errno.EEXIST:

raise

换句话说,我们尝试创建目录,但是如果它们已经存在,我们会忽略该错误。另一方面,报告任何其他错误。例如,如果您事先创建dir’a’并从中删除所有权限,您将得到一个OSError带有errno.EACCES(Permission denied,错误13)的引发。

检查os.makedirs :(它确保存在完整路径。)

为了处理目录可能存在的事实,请捕获OSError。(如果exist_ok为False(默认值),如果目标目录已经存在,则会引发OSError。)

importostry:os.makedirs('./path/to/somewhere')

except OSError:

pass

洞察这种情况的具体情况

你在特定的路径下给出一个特定的文件,然后从文件路径中取出目录。然后,确保您有目录后,您尝试打开一个文件进行阅读。对此代码发表评论:

filename= "/my/directory/filename.txt"dir=os.path.dirname(filename)

我们想避免覆盖内置函数,dir。另外,filepath或者也许可能fullfilepath是一个更好的语义名称比filename这样写得更好:

importos

filepath= '/my/directory/filename.txt'directory=os.path.dirname(filepath)

你的最终目标是打开这个文件,你最初说,为了写作,但你基本上正在接近这个目标(基于你的代码),就像这样,它打开阅读文件:

if notos.path.exists(directory):os.makedirs(directory)f=file(filename)

假设开放阅读

你为什么要为你希望在那里并能够阅读的文件创建一个目录?

试图打开文件。

withopen(filepath) asmy_file:do_stuff(my_file)

如果目录或文件不存在,您将得到一个IOError关联的错误编号:errno.ENOENT将指向正确的错误编号,而不管您的平台。如果你愿意,你可以抓住它,例如:

importerrnotry:

withopen(filepath) asmy_file:do_stuff(my_file)

except IOError aserror:

iferror.errno==errno.ENOENT:

print 'ignoring error because directory or file is not there'

else:

raise

假设我们正在写作

这可能是你想要的。

在这种情况下,我们可能没有面临任何竞争条件。所以,就像你一样,但要注意写作时,你需要用w模式打开(或a追加)。这也是使用上下文管理器打开文件的Python最佳实践。

importosif notos.path.exists(directory):os.makedirs(directory)

withopen(filepath, 'w') asmy_file:do_stuff(my_file)

但是,假设我们有几个Python进程试图将他们所有的数据放到同一个目录中。那么我们可能会争夺目录的创建。在这种情况下,最好将makedirs调用包装在try-except块中。

importosimporterrnoif notos.path.exists(directory):

try:os.makedirs(directory)

except OSError aserror:

iferror.errno!=errno.EEXIST:

raise

withopen(filepath, 'w') asmy_file:do_stuff(my_file)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值