有没有办法mkdir -p
在Python中获得类似于shell的功能.我正在寻找除系统调用之外的解决方案.我确信代码少于20行,我想知道是否有人写过它?
mkdir -p
功能如下:
import errno import os def mkdir_p(path): try: os.makedirs(path) except OSError as exc: # Python >2.5 if exc.errno == errno.EEXIST and os.path.isdir(path): pass else: raise
对于Python≥3.2,os.makedirs
有一个可选的第三个参数 exist_ok
,当为true时,启用该mkdir -p
功能 - 除非 mode
提供,并且现有目录具有与预期目录不同的权限; 在这种情况下,OSError
如前所述.
对于Python≥3.5,还有pathlib.Path.mkdir
:
import pathlib pathlib.Path("/tmp/path/to/desired/directory").mkdir(parents=True, exist_ok=True)
该exist_ok
参数是在Python 3.5中添加的.
在Python> = 3.2中,那就是
os.makedirs(path, exist_ok=True)
在早期版本中,使用@ tzot的答案.
这比捕获异常更容易:
import os if not os.path.exists(...): os.makedirs(...)
免责声明此方法需要两个系统调用,在某些环境/条件下更容易受到竞争条件的影响.如果您正在编写比在受控环境中运行的简单一次性脚本更复杂的东西,那么最好使用只需要一次系统调用的已接受答案.
更新2012-07-27
我很想删除这个答案,但我认为下面的评论帖中有价值.因此,我将其转换为维基.
最近,我发现了这个distutils.dir_util.mkpath:
In [17]: from distutils.dir_util import mkpath In [18]: mkpath('./foo/bar') Out[18]: ['foo', 'foo/bar']
mkdir -p
如果文件已存在,则会出错:
$ touch /tmp/foo $ mkdir -p /tmp/foo mkdir: cannot create directory `/tmp/foo': File exists
因此,对先前建议的改进将是返回(在检查时)raise
异常.os.path.isdir
False
errno.EEXIST
(更新)另见这个高度相似的问题 ; 我同意接受的答案(和警告),除了我建议os.path.isdir
而不是os.path.exists
.
(更新)根据评论中的建议,完整功能如下所示:
import os def mkdirp(directory): if not os.path.isdir(directory): os.makedirs(directory)
使用python3标准库中的Pathlib:
Path(mypath).mkdir(parents=True, exist_ok=True)
如果父母是真的,那么根据需要创建这条路径的任何失踪父母; 它们是使用默认权限创建的,不考虑模式(模仿POSIX mkdir -p命令).如果exist_ok为false(缺省值),则在目标目录已存在的情况下引发FileExistsError.
如果exist_ok为true,则将忽略FileExistsError异常(与POSIX mkdir -p命令相同),但前提是最后一个路径组件不是现有的非目录文件.
在版本3.5中更改:添加了exist_ok参数.
正如其他解决方案中所提到的,我们希望能够在模仿行为的同时点击文件系统一次mkdir -p
.我不认为这是可能的,但我们应该尽可能接近.
代码优先,稍后说明:
import os import errno def mkdir_p(path): """ 'mkdir -p' in Python """ try: os.makedirs(path) except OSError as exc: # Python >2.5 if exc.errno == errno.EEXIST and os.path.isdir(path): pass else: raise
由于对@ tzot的回答的注释表明在实际创建目录之前检查是否可以创建目录存在问题:在此期间您无法判断是否有人更改了文件系统.这也符合Python要求宽恕的风格,而不是许可.
所以我们要做的第一件事就是尝试制作目录,然后如果出错,找出原因.
正如Jacob Gabrielson指出的那样,我们必须寻找的案例之一就是我们试图放置目录的文件已存在.
用mkdir -p
:
$ touch /tmp/foo $ mkdir -p /tmp/foo mkdir: cannot create directory '/tmp/foo': File exists
Python中的类似行为是引发异常.
因此,如果是这种情况,我们必须解决.不幸的是,我们做不到.我们从makedirs得到相同的错误消息,无论目录是否存在(正常)或存在防止创建目录(坏)的文件.
找出问题的唯一方法是再次检查文件系统,看看那里是否有目录.如果有,则以静默方式返回,否则引发异常.
唯一的问题是文件系统现在可能处于与调用makedirs时不同的状态.例如:存在导致makedirs失败的文件,但现在一个目录就在其位置.这并不重要,因为在最后一个文件系统调用目录时,该函数只会在不引发异常的情况下以静默方式退出.
我认为Asa的答案基本上是正确的,但是你可以将它扩展一点,以便更像mkdir -p
:
import os def mkdir_path(path): if not os.access(path, os.F_OK): os.mkdirs(path)
要么
import os import errno def mkdir_path(path): try: os.mkdirs(path) except os.error, e: if e.errno != errno.EEXIST: raise
这些都处理路径已经静默存在的情况,但让其他错误冒出来.
功能声明;
import os def mkdir_p(filename): try: folder=os.path.dirname(filename) if not os.path.exists(folder): os.makedirs(folder) return True except: return False
用法:
filename = "./download/80c16ee665c8/upload/backup/mysql/2014-12-22/adclient_sql_2014-12-22-13-38.sql.gz" if (mkdir_p(filename): print "Created dir :%s" % (os.path.dirname(filename))