我正在尝试将以下伪代码转换为Python:
If <directory> does not exist: Create all subdirectories for <directory> Create a file in <directory>
这听起来很简单,可以通过os.makedirs
和os.path.isdir
完成:
if not os.path.isdir('/some/path'):
os.makedirs('/some/path')
open('/some/path/test.txt', 'w')
然而,经过进一步检查,显然存在竞争条件。请考虑以下时间表:
/some/path
)不存在True
/some/path
)makedirs
引发OSError
异常,因为该目录已存在如果目录最初存在但在最后一行执行之前被另一个进程删除,也会出现问题。
说到Python,“要求宽恕比获得许可更容易。”考虑到这一点,上面的片段可以写得更好:
try:
os.makedirs('/some/path')
except OSError:
pass
open('/some/path/test.txt', 'w')
这解决了上述两个问题,但创建了第三个:os.makedirs
在出现下列情况之一时引发OSError
异常:
这意味着无法确定引发异常的两个条件中的哪一个。换句话说,实际的失败将被忽略,这不是我想要的。
我该如何解决这个问题?
答案 0 :(得分:3)
我会注意到所有这些在python 3中都相当明显; FileExistsError
和PermissionError
是独立的(OSError
的子类)您可以捕获的异常,os.makedirs
甚至有一个exist_ok
kwarg来压制前者请确认已存在的目录。
如果您想检查OSError
的原因,那么该信息位于e.args
中的元组中(或者如果您只想查看错误代码,则可选e.errno
):
try:
os.makedirs('/etc/python')
except OSError as e:
print e.args
(17, 'File exists')
try:
os.makedirs('/etc/stuff')
except OSError as e:
print e.args
(13, 'Permission denied')
try:
os.makedirs('/etc/stuff')
except OSError as e:
print e.errno
13
因此,您必须进行一些内省,并在except
块中以不同方式处理这两个错误代码。