質問
この質問にはすでに回答があります:
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で追加されました。
他のヒント
これは、例外をトラップするよりも簡単です。
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
)の場合。
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の回答に基づいていますが、ツリーの一部が既に存在する場合はバグが修正されています