osモジュールが提供するrename関数とrenames関数を使って、ファイルやディレクトリの名前を変更したり、移動したりする方法を紹介する。
この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。
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モジュールを使用する方法を紹介する。
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)を実行し、そのターミナルからこのコードを実行した結果を以下に示す。
このようにFileExistsError例外が発生し、ファイルの名前は変更されない。
これに対して、UNIXではパラメーターsrcに指定したファイルで、パラメーターdstに指定したファイルが置き換えられる。以下はmacOSでVS Codeを実行して、そのターミナルから上記のコードを実行した結果だ。
また、パラメーター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.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
Copyright© Digital Advantage Corp. All Rights Reserved.