[解決!Python]ディレクトリを作成/削除するには:osモジュール編解決!Python

osモジュールのmkdir/rmdir/makedirs/removedirs関数とshutilモジュールのrmtree関数を使って、ディレクトリを作成/削除する方法を紹介。

» 2022年06月21日 05時00分 公開
[かわさきしんじDeep Insider編集部]

この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。

「解決!Python」のインデックス

連載目次

import os

# os.mkdir関数を使ったディレクトリ作成
target_dir = 'sample_dir'
os.mkdir(target_dir)
os.mkdir(target_dir)  # FileExistsError

# os.rmdir関数を使ったディレクトリ削除
target_dir = 'sample_dir'
os.rmdir(target_dir)

# os.makedirs関数を使った再帰的なディレクトリ作成
target_dir = 'sample_dir/dir2/dir3'
os.makedirs(target_dir)

# os.rmdir関数は空でないディレクトリは削除できない
target_dir = 'sample_dir/dir2'
os.rmdir(target_dir)  # OSError:dir2ディレクトリにはdir3ディレクトリがある

# os.removedirs関数を使った再帰的なディレクトリ削除
os.removedirs(target_dir)  # 最下層のディレクトリから順に削除していく

# os.removedirs関数は途中に空でないディレクトリがあるとそこで削除を終了する
target_dir = 'sample_dir/dir2/dir3'
os.makedirs(target_dir)
os.mkdir('sample_dir/dir2/foo')
os.removedirs(target_dir)  # dir3を削除した後、dir2が空ではないので削除できない

# 指定したディレクトリの内容を全て削除する
import shutil

shutil.rmtree('sample_dir')


ディレクトリの作成/削除に使えるモジュール

 Pythonのコードからファイルシステム上でディレクトリを作成したり削除したりするには幾つかの方法がある。

  • osモジュールを使用する
  • pathlibモジュールを使用する
  • shutilモジュールを使用する(再帰的なディレクトリ削除)

 本稿ではこのうちosモジュールを使用する方法とshutilモジュールのrmtree関数を使ってディレクトリを再帰的に削除する方法を紹介する。

os.mkdir関数を使ったディレクトリ作成

 ディレクトリを作成/削除するには、osモジュールが提供する以下の関数を使う。

  • os.mkdir関数:ディレクトリを作成
  • os.makedirs関数:ディレクトリを再帰的に作成(複数階層のディレクトリ作成)
  • os.rmdir関数:ディレクトリを削除
  • os.removedirs関数:ディレクトリを再帰的に削除(複数階層のディレクトリ削除)

 まずはos.mkdir関数を使ってディレクトリを作成し、os.rmdir関数を使ってそのディレクトリを削除してみよう。

 os.mkdir関数の一番簡単な使い方は作成したいディレクトリの名前を引数に指定することだ。以下に例を示す。

import os

target_dir = 'sample_dir'
os.mkdir(target_dir)
os.mkdir(target_dir)  # FileExistsError


 この例はカレントディレクトリにsample_dirという名前のディレクトリを作成するものだ。os.mkdir関数は既に存在するディレクトリを作成しようとすると、FileExistsError例外となる点には注意しよう。例外を回避するのであれば、以下のようにos.pathモジュールのexists関数を使用して、ディレクトリがないことを確認する。

if not os.path.exists(target_dir):
    os.mkdir(target_dir)
else:
    print(f'{target_dir} already exists')


 あるいは、pathlibモジュールのPathクラスのインスタンスが持つmkdirメソッドにはexist_okパラメーターがあり、これにTrueを指定すると既存のディレクトリを作成しようとしたときに例外が発生しないようになる(pathlibモジュールを使ったディレクトリの作成/削除については別稿で紹介する)。

os.rmdir関数を使ったディレクトリ削除

 上で作成したsample_dirディレクトリを削除するには、os.rmdir関数にそのディレクトリを指定するだけだ。以下に例を示す。

target_dir = 'sample_dir'
os.rmdir(target_dir)


 存在しないディレクトリを削除しようとしたときには、FileNotFoundError例外が発生する。また、削除対象のディレクトリは空である必要がある。つまり、ファイルやディレクトリを含まないディレクトリしか削除できない(空でないディレクトリを削除しようとするとOSError例外が発生し、ディレクトリが空ではないというメッセージが伝えられる)。

os.makedirs関数を使った再帰的なディレクトリ作成

 os.mkdir関数で一度に作成できるのは指定したディレクトリ1つだ。存在しない複数階層のディレクトリを作成することはできない。例えば、カレントディレクトリの下にsample_dirディレクトリを、その下にdir2ディレクトリを、さらにその下にdir3ディレクトリを作成したいというときには、os.mkdir関数を3回呼び出す必要がある。

 こうしたときには、os.makedirs関数を使用する。この関数は指定したディレクトリ(上の例なら「sample_dir/dir2/dir3」)を作成する上で必要なディレクトリを全て作成してくれる。以下に例を示す。

target_dir = 'sample_dir/dir2/dir3'
os.makedirs(target_dir)


 このような複数階層のディレクトリをos.rmdir関数で削除するには、最下層のディレクトリから順番に削除していく必要がある(このときには上で述べたように、それぞれのディレクトリが空である必要もある)。

 例えば、上の例ではsample_dir/dir2/dir3ディレクトリを作成しているが、ここで下のようなコードで、sample_dir/dir2ディレクトリを削除しようとすると、OSError例外が発生する。

target_dir = 'sample_dir/dir2'
os.rmdir(target_dir)  # OSError


 これはsample_dir/dir2ディレクトリの下にはdir3ディレクトリがある、つまり空ではないために削除できないからだ。複数階層のディレクトリをまとめて削除するには、次に紹介するos.removedirs関数を使用する。

os.removedirs関数を使った再帰的なディレクトリ削除

 os.removedirs関数は指定したディレクトリを再帰的に削除する。注意点は削除対象の最上位のディレクトリを指定するのではなく、削除したいディレクトリパス全体を指定する点だ。以下に例を示す。

target_dir = 'sample_dir/dir2/dir3'
os.removedirs(target_dir)  # 最下層のディレクトリから順に削除していく


 これは上で作成したsample_dir/dir2/dir3ディレクトリをまるごと削除するコードである。

 なお、os.rmdir関数と同様、削除対象の個々のディレクトリは空である必要がある。上のコード例であれば、まずdir3ディレクトリが(空なら)削除され、次にdir2が(空なら)削除され、最後にdir1が(空なら)削除される。

 途中のディレクトリが空でないときには、そこでディレクトリの削除処理が終了する。それよりも下層にあって削除されたディレクトリは削除されたままとなる。以下に例を示す。

target_dir = 'sample_dir/dir2/dir3'
os.makedirs(target_dir)
os.mkdir('sample_dir/dir2/foo')
os.removedirs(target_dir)  # dir3を削除した後、dir2が空ではないので削除できない


 この例ではsample_dir/dir2/dir3ディレクトリを作成した後、sample_dir/dir2ディレクトリの下にfooディレクトリを作成している。そして、sample_dir/dir2/dir3ディレクトリを再帰的に削除しようとしているが、dir3ディレクトリを削除しても、dir2ディレクトリにはまだfooディレクトリがある(空ではない)ので、そこでディレクトリ全体の削除処理が終了する(ただし、例外は発生しないので注意すること)。

 このことは以下のコードで確認できる。

d_entries = [item for item in os.scandir('sample_dir')]
print(d_entries)  # [<DirEntry 'dir2'>]

d_entries = [item for item in os.scandir('sample_dir/dir2')]
print(d_entries)  # [<DirEntry 'foo'>]


 最初の2行はsample_dirディレクトリの下にどんなファイル/ディレクトリがあるかを調べるものだ。結果を見ると、dir2ディレクトリが残っていることが分かる。

 次の2行はdir2ディレクトリにどんなファイル/ディレクトリがあるかを調べるものだ。結果を見ると、dir3ディレクトリは削除されたが、fooディレクトリが残っていることが分かる。このために、os.removedirs関数は途中でディレクトリ削除処理を中断したということだ。

指定したディレクトリの内容を全て削除する

 上のようにディレクトリ階層の中にさまざまなファイルやディレクトリが存在しているときには、os.removedirs関数は役には立たない。os.listdir関数やos.scandir関数を使って自分でディレクトリを走査しながら、ファイルやディレクトリを下層から上層に向けて削除していくコードを書いてもよいが、shutilモジュールのrmtree関数が使うのが簡単だろう。以下に使用例を示す。

import shutil

shutil.rmtree('sample_dir')


「解決!Python」のインデックス

解決!Python

Copyright© Digital Advantage Corp. All Rights Reserved.

スポンサーからのお知らせPR

注目のテーマ

Microsoft & Windows最前線2025
AI for エンジニアリング
ローコード/ノーコード セントラル by @IT - ITエンジニアがビジネスの中心で活躍する組織へ
Cloud Native Central by @IT - スケーラブルな能力を組織に
システム開発ノウハウ 【発注ナビ】PR
あなたにおすすめの記事PR

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。