mkdir -p functionality in Python [duplicate]

2019-01-01 01:34发布

This question already has an answer here:

Is there a way to get functionality similar to mkdir -p on the shell from within Python. I am looking for a solution other than a system call. I am sure the code is less than 20 lines, and I am wondering if someone has already written it?

标签: python mkdir
12条回答
倾城一夜雪
2楼-- · 2019-01-01 01:55
import os
import tempfile

path = tempfile.mktemp(dir=path)
os.makedirs(path)
os.rmdir(path)
查看更多
无色无味的生活
3楼-- · 2019-01-01 01:57

mkdir -p gives you an error if the file already exists:

$ touch /tmp/foo
$ mkdir -p /tmp/foo
mkdir: cannot create directory `/tmp/foo': File exists

So a refinement to the previous suggestions would be to re-raise the exception if os.path.isdir returns False (when checking for errno.EEXIST).

(Update) See also this highly similar question; I agree with the accepted answer (and caveats) except I would recommend os.path.isdir instead of os.path.exists.

(Update) Per a suggestion in the comments, the full function would look like:

import os
def mkdirp(directory):
    if not os.path.isdir(directory):
        os.makedirs(directory) 
查看更多
无与为乐者.
4楼-- · 2019-01-01 01:59

With Pathlib from python3 standard library:

Path(mypath).mkdir(parents=True, exist_ok=True)

If parents is true, any missing parents of this path are created as needed; they are created with the default permissions without taking mode into account (mimicking the POSIX mkdir -p command). If exist_ok is false (the default), an FileExistsError is raised if the target directory already exists.

If exist_ok is true, FileExistsError exceptions will be ignored (same behavior as the POSIX mkdir -p command), but only if the last path component is not an existing non-directory file.

Changed in version 3.5: The exist_ok parameter was added.

查看更多
浮光初槿花落
5楼-- · 2019-01-01 01:59

Function declaration;

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

usage :

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))
查看更多
梦该遗忘
6楼-- · 2019-01-01 02:04

As mentioned in the other solutions, we want to be able to hit the file system once while mimicking the behaviour of mkdir -p. I don't think that this is possible to do, but we should get as close as possible.

Code first, explanation later:

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

As the comments to @tzot's answer indicate there are problems with checking whether you can create a directory before you actually create it: you can't tell whether someone has changed the file system in the meantime. That also fits in with Python's style of asking for forgiveness, not permission.

So the first thing we should do is try to make the directory, then if it goes wrong, work out why.

As Jacob Gabrielson points out, one of the cases we must look for is the case where a file already exists where we are trying to put the directory.

With mkdir -p:

$ touch /tmp/foo
$ mkdir -p /tmp/foo
mkdir: cannot create directory '/tmp/foo': File exists

The analogous behaviour in Python would be to raise an exception.

So we have to work out if this was the case. Unfortunately, we can't. We get the same error message back from makedirs whether a directory exists (good) or a file exists preventing the creation of the directory (bad).

The only way to work out what happened is to inspect the file system again to see if there is a directory there. If there is, then return silently, otherwise raise the exception.

The only problem is that the file system may be in a different state now than when makedirs was called. eg: a file existed causing makedirs to fail, but now a directory is in its place. That doesn't really matter that much, because the the function will only exit silently without raising an exception when at the time of the last file system call the directory existed.

查看更多
荒废的爱情
7楼-- · 2019-01-01 02:05

Recently, I found this distutils.dir_util.mkpath:

In [17]: from distutils.dir_util import mkpath

In [18]: mkpath('./foo/bar')
Out[18]: ['foo', 'foo/bar']
查看更多
登录 后发表回答