1. ホーム
  2. パイソン

[解決済み】ネストされたディレクトリを安全に作成するには?

2022-03-17 19:38:46

質問

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 (kanjaさん、Blairさん、Douglasさん、ありがとうございます)。今あるのはこれです。

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

のフラグはありますか? open() これを自動的に行うには?

どのように解決するのですか?

Python ≥ 3.5 では、以下のようにします。 pathlib.Path.mkdir :

from pathlib import Path
Path("/my/directory").mkdir(parents=True, exist_ok=True)

古いバージョンのPythonについては、良い資質を持った2つの答えがあり、それぞれに小さな欠点があるので、私の考えを述べます。

試す os.path.exists を、そして os.makedirs を作成しました。

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

コメントなどで指摘されているように、レースコンディションがあります。 os.path.existsos.makedirs の呼び出しでは os.makedirs で失敗します。 OSError . 残念ながら、ブランケットキャッチの OSError というのは、パーミッション不足、フルディスクなど、他の要因によるディレクトリの作成失敗を無視してしまうからです。

一つの選択肢は 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回目のチェックの前にそれを削除したとすると、まだ騙される可能性があるのです。

アプリケーションによっては、同時操作の危険性が、ファイルのパーミッションなど他の要因によってもたらされる危険性よりも高い、あるいは低いかもしれません。開発者は、実装を選択する前に、開発中の特定のアプリケーションとその予想される環境についてもっと知る必要があるでしょう。

最近のPythonは、このコードをかなり改良しています。 FileExistsError (3.3+では)・・・。

try:
    os.makedirs("path/to/directory")
except FileExistsError:
    # directory already exists
    pass

...そして のキーワード引数です。 os.makedirs という exist_ok (3.2+の場合)です。

os.makedirs("path/to/directory", exist_ok=True)  # succeeds even if directory exists.