質問

    

この質問にはすでに回答があります:

         

Python内からシェルで mkdir -p に似た機能を取得する方法はありますか。システムコール以外のソリューションを探しています。コードは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 にはオプションの3番目の引数 exist_ok 。trueの場合、 mkdir -p 機能を有効にします— unless mode が提供されており、既存のディレクトリには意図したものとは異なる権限があります。その場合、以前と同様に OSError が発生します。

更新2

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(...)

免責事項このアプローチでは、特定の環境/条件下で競合状態になりやすい2つのシステムコールが必要です。制御された環境で実行される単純なスローアウェイスクリプトよりも洗練されたものを書いている場合は、1つのシステムコールのみを必要とする受け入れられた答えを使用する方が良いでしょう。

2012-07-27の更新

この回答を削除したいのですが、下のコメントスレッドに価値があると思います。そのため、私はそれをwikiに変換しています。

最近、 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

したがって、前の提案の改良点は、 os.path.isdir False を返した場合に例外を再 raise することです(チェック時 errno.EEXIST )の場合。

(更新)こちらもご覧ください

他のソリューションで述べたように、 mkdir -p の動作を模倣しながら、ファイルシステムに1回アクセスできるようにしたいと考えています。私はこれができるとは思いませんが、できるだけ近づける必要があります。

コードを最初に、後で説明:

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

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パラメーターが追加されました。

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))

私は個人的に次のことで成功しましたが、私の機能はおそらく「このディレクトリが存在することを確認してください」のように呼ばれるべきです:

def mkdirRecursive(dirpath):
    import os
    if os.path.isdir(dirpath): return

    h,t = os.path.split(dirpath) # head/tail
    if not os.path.isdir(h):
        mkdirRecursive(h)

    os.mkdir(join(h,t))
# end mkdirRecursive
import os
import tempfile

path = tempfile.mktemp(dir=path)
os.makedirs(path)
os.rmdir(path)
import os
from os.path import join as join_paths

def mk_dir_recursive(dir_path):

    if os.path.isdir(dir_path):
        return
    h, t = os.path.split(dir_path)  # head/tail
    if not os.path.isdir(h):
        mk_dir_recursive(h)

    new_path = join_paths(h, t)
    if not os.path.isdir(new_path):
        os.mkdir(new_path)

@Dave Cの回答に基づいていますが、ツリーの一部が既に存在する場合はバグが修正されています

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top