検索
連載

[解決!Python]ファイルやディレクトリを名前変更/移動するには:osモジュール編解決!Python

osモジュールが提供するrename関数とrenames関数を使って、ファイルやディレクトリの名前を変更したり、移動したりする方法を紹介する。

PC用表示 関連情報
Share
Tweet
LINE
Hatena
「解決!Python」のインデックス

連載目次

import os

with open('a.txt', 'wt') as f:  # a.txtを作成
    pass

with open('b.txt', 'wt') as f:  # b.txtを作成
    pass

# ファイルの名前変更
os.rename('a.txt', 'c.txt'# UNIX/Windows: 成功

# ファイル名を既存のファイルの名前に変更しようとする
# Windowsではファイル名を既存のファイルの名前には変更できない
# UNIXでは既存のファイルが警告なしに置き換えられる
os.rename('b.txt', 'c.txt'# UNIX: 成功、Windows: FileExistsError

# ファイル名を既存のディレクトリの名前に変更しようとすると例外となる
os.mkdir('mydir')
os.rename('c.txt', 'mydir'# IsADirectoryError/FileExistsError

# ファイルの移動
os.rename('c.txt', 'mydir/d.txt'# UNIX/Windows: 成功

# ディレクトリの名前変更
os.makedirs('dir1/dir2/dir3')
os.rename('dir1', 'dir4')

# 既存のディレクトリの名前に変更しようとした場合
os.mkdir('dir5')
os.rename('dir4', 'dir5'# Windows:FileExistsError

os.makedirs('dir6/dir7'# 空でないディレクトリ「dir6」を作成
os.rename('dir5', 'mydir'# ディレクトリが空でないと失敗する

# ディレクトリの移動
os.rename('dir5', 'dir6/dir7/dir5')

os.mkdir('a')
os.rename('a', 'x/a'# FileNotFoundError


ファイルやディレクトリの名前を変更したり、移動したりする方法

 ファイルやディレクトリの名前を変更したり、別のディレクトリに移動したりするには幾つかの方法がある。

  • osモジュールのrename/renames関数を使用する
  • pathlibモジュールのPathクラスのrenameメソッドを使用する
  • shutilモジュールのmove関数を使用する

 本稿では、このうちosモジュールを使用する方法を紹介する。

os.rename関数

 os.rename関数の基本的な構文を以下に示す。

os.rename(src, dst)


 パラメーターsrcには変更前のファイルやディレクトリの名前を、パラメーターdstには変更後の名前を指定する。変更後の名前に「'dst_dir/dst_filename.ext」のようにディレクトリが含まれていれば、ファイルやディレクトリがそこに移動される。なお、os.renames関数はプラットフォームがUNIXかWindowsかで動作が異なる点には注意されたい(以下の表を参照)。

移動元 移動先 UNIX Windows
ファイル 存在しない 成功 成功
ファイル ファイル 成功 FileExistsError
ファイル ディレクトリ IsADirectoryError FileExistsError
ディレクトリ 存在しない 成功 成功
ディレクトリ ファイル NotADirectoryError FileExistsError
ディレクトリ ディレクトリ(空) 成功 FileExistsError
ディレクトリ ディレクトリ(空ではない) OSError FileExistsError
os.rename関数の動作

ファイルの名前変更

 ファイルの名前を変更する例を以下に示す。

import os

with open('a.txt', 'wt') as f:  # a.txtを作成
    pass

with open('b.txt', 'wt') as f:  # b.txtを作成
    pass

# ファイルの名前変更
os.rename('a.txt', 'c.txt'# UNIX/Windows: 成功


 この例では、a.txtファイルとb.txtファイルという空のファイルを2つ作成して、そのうちのa.txtファイルの名前を「b.txt」に変更している。os.rename関数のパラメーターdstに存在しないファイルを指定した場合には、UNIXでもWindowsでもこれは成功して、ファイルの名前が変更される。

 しかし、パラメーターdstに既存のファイルの名前を指定すると、UNIXでは成功し、WindowsではFileExistsError例外が発生する。

os.rename('b.txt', 'c.txt'# UNIX: 成功、Windows: FileExistsError


 この例は、最初に作成してあったb.txtファイルの名前を、os.rename関数で「c.txt」に変更しようとしている(この前のコード例でa.txtファイルをc.txtファイルに変更している点に注意)。

 WindowsでVisual Studio Code(以下、VS Code)を実行し、そのターミナルからこのコードを実行した結果を以下に示す。

Windowsではos.rename関数のパラメーターdstに既存ファイルの名前を指定すると例外が発生する
Windowsではos.rename関数のパラメーターdstに既存ファイルの名前を指定すると例外が発生する

 このようにFileExistsError例外が発生し、ファイルの名前は変更されない。

 これに対して、UNIXではパラメーターsrcに指定したファイルで、パラメーターdstに指定したファイルが置き換えられる。以下はmacOSでVS Codeを実行して、そのターミナルから上記のコードを実行した結果だ。

macOSでos.rename関数により既存ファイルが上書きされた
macOSでos.rename関数により既存ファイルが上書きされた

 また、パラメーターdstに既存のディレクトリの名前を指定した場合は、UNIX/Windowsのいずれでも失敗し、ファイルの名前は変更されない。

os.mkdir('mydir')
os.rename('c.txt', 'mydir'# IsADirectoryError/FileExistsError


ファイルの移動

 既に述べたが、os.rename関数のパラメーターdstにディレクトリを含めると、ファイルはそこに移動する。以下に例を示す。

os.rename('c.txt', 'mydir/d.txt'# UNIX/Windows: 成功


 これは、上でa.txtファイルから名前を変更した(あるいは、その後、b.txtファイルで上書きされた)c.txtファイルを、先ほど作成したmydirディレクトリに移動すると同時に、そのファイル名を「d.txt」に変更する例だ。

 ただし、パラメーターdstに指定したパスに存在しないディレクトリが含まれていると失敗する。これを回避するには、本稿の最後に紹介するos.renames関数を使うとよい。

ディレクトリの名前変更

 ディレクトリの名前変更に関しては、ファイルの名前変更と同様だ。つまり、以下のようになる。

移動元 移動先 UNIX Windows
ディレクトリ 存在しない 成功 成功
ディレクトリ ファイル NotADirectoryError FileExistsError
ディレクトリ ディレクトリ(空) 成功 FileExistsError
ディレクトリ ディレクトリ(空ではない) OSError FileExistsError
os.rename関数の動作

 変更後の名前にファイルやディレクトリが存在しないものを指定すれば、UNIXでもWindowsでも名前が変更される。既存ファイルの名前をパラメーターdstに指定すると、どちらも例外となる。空のディレクトリの名前をパラメーターdstに指定すると、UNIXでは名前が変更され、Windowsでは例外となる。空ではないディレクトリなら、UNIXでもWindowsでも失敗する。

 以下に例を示す。

os.makedirs('dir1/dir2/dir3')
os.rename('dir1', 'dir4')


 これは「dir1」→「dir2」→「dir3」という階層構造を持つディレクトリを作成し、そのトップレベルのディレクトリ「dir1」の名前を「dir4」に変更する例だ。

 以下にWindows環境で試した結果を示す。

ディレクトリの名前変更
ディレクトリの名前変更

 画像右上の[エクスプローラー]ビューを見ると、「dir4/dir2/dir3」とトップレベルのディレクトリ名が変更されていることが分かるはずだ。

 以下は上で名前を変更したdir4ディレクトリを、既存のディレクトリの名前である「dir5」の名前に変更しようとする例だ。

os.mkdir('dir5')
os.rename('dir4', 'dir5'# Windows:FileExistsError


 dir5ディレクトリは上で作成したばかりなので空である。そのため、UNIXでは名前が変更される。しかし、Windowsでは、既存のディレクトリやファイルの名前をパラメーターdstに指定した場合には例外となる。

 以下は空でないディレクトリの名前をパラメーターdstに指定する例だ。

os.makedirs('dir6/dir7'# 空でないディレクトリ「dir6」を作成
os.rename('dir5', 'dir6'# ディレクトリが空でないと失敗する


 ここではdir5ディレクトリの名前を「dir6」に変更しようとしているが、dir6ディレクトリは既に存在していて、dir7ディレクトリがその下にある(空ではない)。そのため、UNIXではOSError例外が、WindowsではFileExistsError例外が発生する。

ディレクトリの移動

 ディレクトリの移動もファイルの移動と同様で、パラメーターdstにディレクトリを含んだパスを渡す。以下に例を示す。

os.rename('dir5', 'dir6/dir7/dir5')


 この例は、先ほどの例で使用したdir5ディレクトリを、やはり上で使用したdir6/dir7ディレクトリの下に(「dir5」という名前で)移動しようとするものだ。この場合、dir6/dir7ディレクトリにはdir5ディレクトリがないので成功する。

 ただし、パラメーターdstに指定したパスに存在しないディレクトリが含まれていると失敗する。これを回避するには、次に紹介するos.renames関数を使うとよい。

os.renames関数

 os.renames関数は再帰的にファイルやディレクトリの名前を変更する。os.rename関数との違いは、パラメーターdstに指定したパスに存在しないディレクトリが含まれている場合に、必要なものを自動的に作成してくれる点にある。

 以下に例を示す。ここではディレクトリを例とするが、ファイルでも同じだ。

os.mkdir('a')
os.rename('a', 'x/a'# FileNotFoundError


 上のコードは、aディレクトリを作成して、os.rename関数でそれをxディレクトリの下に移動(して、x/aディレクトリに)しようとしている。しかし、「x」という名前のディレクトリはないので、FileNotFoundError例外が発生する。

 一方、以下のようにos.renames関数を使うと、自動的にxディレクトリを作成して、そこにaディレクトリを移動してくれる。

os.renames('a', 'x/a'# OK


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

解決!Python

Copyright© Digital Advantage Corp. All Rights Reserved.

[an error occurred while processing this directive]
ページトップに戻る