ディレクトリが存在しない場合、どうやって作ったらいいの? [Python]

このエントリーをはてなブックマークに追加

質問:

ファイルが書き込まれるディレクトリが存在するかどうかを調べて、もし存在しない場合は、Pythonを使ってディレクトリを作るための最もエレガントな方法って何?
以下は試したんだけど:

import os
file_path = "/my/directory/filename.txt"
directory = os.path.dirname(file_path)
try:
os.stat(directory)
except:
os.mkdir(directory)
f = file(filename)

どういうわけかos.path.existsっていうのがあるのを知らなかったので、こうしたんだけど:

def ensure_dir(file_path):
directory = os.path.dirname(file_path)
if not os.path.exists(directory):
os.makedirs(directory)

これが自動的に行われるようにするような、 “open”のためのフラグってある?

By Parand | 質問日時: 2008年11月7日 18:56



回答1:

2つ答えがあって、それぞれに良し悪しがあるんだけど、僕が書くなら:

os.path.existsを試してみて、ディレクトリを作るにはos.makedirsはどうかな。

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

でもこれってちょっとややこしいんだ — もしディレクトリが os.path.existsos.makedirs呼び出しの間に作られたら、os.makedirsOSErrorで失敗する。残念だけど、助けを出すOSErrorとそれを実行し続けることはフールプルーフ(foolproof)じゃない。なぜなら、例えばアクセス許可がない場合とかディスク容量が無いとかの他の要因でディレクトリ作成が失敗してもそれを無視するからね。

1つのオプションは OSErrorをトラップし、埋め込まれたエラーコードを調べること。(PythonのOSErrorから情報を取得するためのクロスプラットフォームの方法はありますか?参照):

import os, errno
try:
os.makedirs(directory)
except OSError as e:
if e.errno != errno.EEXIST:
raise

あるいは、2つ目の os.path.existsっていうのも考えられるけど、仮に別の人が一つ目のチェックの後にディレクトリを作って、2つ目のチェックの前に削除してしまう、みたいな場合でもうまくいかない可能性がある。

アプリケーションによって、同時操作の危険性はファイルアクセス権とかの他の要因によって引き起こされる危険性よりも高かったり低かったり刷るから、開発者は実装を選ぶ前に開発されてる特定のアプリケーションと期待されてる環境の詳細をよく知ってる必要があるよね。

By Blair Conrad | 回答日時: 2008年11月7日 19:06



回答2:

try exceptとerrnoモジュールの正しいエラーコードを使えば、競合状態(race condition)の可能性を排除できるし、クロスプラットフォームでもあるよ:

import os
import errno
def make_sure_path_exists(path):
try:
os.makedirs(path)
except OSError as exception:
if exception.errno != errno.EEXIST:
raise

つまり、ディレクトリを作成しようとしますが、すでに存在する場合はエラーを無視する。一方、その他のエラーは報告される。
たとえば、’a’というディレクトリをあらかじめ作成しておき、その中からすべての権限を削除すると、errno.EACCESOSErrorが発生するよ(パーミッションが拒否されました。エラー13)。

By Heikki Toivonen | 回答日時: 2011年2月17日 17:17



回答3:

私は個人的にはos.path.exists()よりも os.path.isdir()を使うのをおすすめするかな:

>>> os.path.exists('/ tmp/dirname')
True
>>> os.path.exists('/ tmp/dirname/filename.etc')
True
>>> os.path.isdir('/ tmp/dirname/filename.etc')
False
>>> os.path.isdir('/ tmp/fakedirname')
False

これがあるとして、

>>> dir = raw_input(":: ")

そして、こんなバカみたいなユーザー入力があると:

:: /tmp/dirname/filename.etc

もしos.path.exists()でテストした場合、引数がos.makedirs()に渡されるから、filename.etcという名前のディレクトリができてしまうことになる。

By crimsonstone | 回答日時: 2009年1月14日 17:57



Source: How can I create a directory if it does not exist?

共有 コメント