949

mkdir -pPython内からシェルと同様の機能を取得する方法はありますか?システムコール以外の解決策を探しています。コードは20行未満だと思いますが、誰かがすでに書いているのではないかと思います。

4

12 に答える 12

1306

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オプションの 3 番目の引数exist_okTrueありmkdir -pます。<em>が指定modeされていて、既存のディレクトリが意図したものとは異なる権限を持っている場合を除きます。その場合、OSError以前のように発生します。

import os
os.makedirs("/tmp/path/to/desired/directory", exist_ok=True)

Python のさらに古いバージョンではos.makedirs、エラーを使用して無視できます。

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
        # possibly handle other errno cases here, otherwise finally:
        else:
            raise
于 2009-03-01T21:51:46.710 に答える
327

Python >=3.2 では、それは

os.makedirs(path, exist_ok=True)

以前のバージョンでは、@tzot の answerを使用してください。

于 2012-06-19T13:21:48.183 に答える
158

これは、例外をトラップするよりも簡単です。

import os
if not os.path.exists(...):
    os.makedirs(...)

免責事項このアプローチでは、特定の環境/条件下での競合状態の影響を受けやすい2つのシステムコールが必要です。制御された環境で実行される単純な使い捨てスクリプトよりも洗練されたものを作成している場合は、1回のシステムコールのみを必要とする受け入れられた回答を使用することをお勧めします。

更新2012-07-27

この答えを削除したくなりますが、以下のコメントスレッドに価値があると思います。そういうものとして、私はそれをウィキに変換しています。

于 2009-03-02T00:48:58.733 に答える
48

最近、私はこのdistutils.dir_util.mkpathを見つけました:

In [17]: from distutils.dir_util import mkpath

In [18]: mkpath('./foo/bar')
Out[18]: ['foo', 'foo/bar']
于 2013-01-15T21:39:43.257 に答える
17

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) 
于 2009-03-02T00:09:10.420 に答える
16

python3標準ライブラリの Pathlib を使用:

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

Parents が true の場合、このパスの欠落している親が必要に応じて作成されます。モードを考慮せずにデフォルトのパーミッションで作成されます (POSIX mkdir -p コマンドを模倣します)。exist_ok が false (デフォルト) の場合、ターゲット ディレクトリが既に存在すると FileExistsError が発生します。

exist_ok が true の場合、FileExistsError 例外は無視されます (POSIX mkdir -p コマンドと同じ動作) が、最後のパス コンポーネントが既存の非ディレクトリ ファイルでない場合のみです。

バージョン 3.5 で変更: exist_ok パラメータが追加されました。

于 2016-02-08T17:02:36.813 に答える
14

他のソリューションで述べたように、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 が指摘しているように、探す必要があるケースの 1 つは、ディレクトリを配置しようとしている場所にファイルが既に存在する場合です。

mkdir -p:

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

Python での類似の動作は、例外を発生させることです。

したがって、これが事実であったかどうかを解決する必要があります。残念ながら、できません。ディレクトリが存在する (良い) か、ディレクトリの作成を妨げるファイルが存在する (悪い) かに関係なく、makedirs から同じエラー メッセージが返されます。

何が起こったのかを解明する唯一の方法は、ファイル システムをもう一度調べて、そこにディレクトリがあるかどうかを確認することです。ある場合は黙って戻り、そうでない場合は例外を発生させます。

唯一の問題は、ファイル システムが makedirs が呼び出されたときとは異なる状態になっている可能性があることです。例: makedirs が失敗する原因となったファイルが存在していましたが、現在はディレクトリがその場所にあります。最後のファイルシステム呼び出し時にディレクトリが存在していた場合、関数は例外を発生させずにサイレントに終了するだけなので、それはそれほど重要ではありません。

于 2012-08-08T08:31:24.557 に答える
10

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

これらは両方とも、パスがすでに存在する場合を黙って処理しますが、他のエラーが発生するのを許します。

于 2009-03-01T21:47:58.777 に答える
2
import os
import tempfile

path = tempfile.mktemp(dir=path)
os.makedirs(path)
os.rmdir(path)
于 2012-08-06T09:47:43.473 に答える