Python, pathlibでファイルの作成・open・読み書き・削除

Modified: | Tags: Python, ファイル処理

Pythonのpathlibモジュールを使ってファイルを新規作成したり読み込み・書き込みを行ったり削除したりする方法について説明する。

pathlibのPathオブジェクトにはopen()メソッドがあり、組み込み関数open()と同様の処理が可能。また、テキストファイルやバイナリファイル全体を読み書きするread_text(), write_text(), read_bytes(), write_bytes()という便利なメソッドもある。

組み込み関数open()についての詳細は以下の記事を参照。

pathlibの基礎、ディレクトリの処理については以下の記事を参照。

本記事のサンプルコードでは以下のようにpathlibモジュールからPathクラスをインポートしている。pathlibは標準ライブラリに含まれているので追加のインストールは不要。

from pathlib import Path

空のファイルを作成、既存ファイルの日時更新: touch()

空のファイルを作成するにはPathオブジェクトのtouch()メソッドを使う。

Path()Pathオブジェクトを生成する。ここではディレクトリを作成し、その中の新たなファイルのパスを指定する。

Path('temp').mkdir()

p_empty = Path('temp/empty_file.txt')
print(p_empty)
# temp/empty_file.txt

print(type(p_empty))
# <class 'pathlib.PosixPath'>

OSによってPosixPathまたはWindowsPathのインスタンスが生成される。Pathの基本については以下の記事を参照。

この時点ではファイルは存在していない。exists()で確認。

print(p_empty.exists())
# False

touch()で空のファイルが新規作成される。

p_empty.touch()

print(p_empty.exists())
# True

デフォルトでは既存のファイルに対してtouch()を実行するとタイムスタンプが更新される。Unixのtouchコマンドと同じ動作。

p_empty.touch()

引数exist_okFalseとすると既存のファイルに対してはエラーとなる。

# p_empty.touch(exist_ok=False)
# FileExistsError: [Errno 17] File exists: 'temp/empty_file.txt'

新規ファイルを作成する場合は直上のディレクトリまでは作成しておく必要がある。中間ディレクトリが存在しないとエラー。

p_empty_new_dir = Path('temp/new_dir/empty_file.txt')

# p_empty_new_dir.touch()
# FileNotFoundError: [Errno 2] No such file or directory: 'temp/new_dir/empty_file.txt'

中間ディレクトリが存在していない場合は、親ディレクトリのPathオブジェクトをparent属性で取得してmkdir()でディレクトリを作成してからtouch()を実行する。

p_empty_new_dir.parent.mkdir(parents=True, exist_ok=True)
p_empty_new_dir.touch()

直上のディレクトリまで存在している場合は以下のように一行で書ける。

Path('temp/empty_file2.txt').touch()

ファイルのopen: open()

Pathオブジェクトのopen()メソッドで、Pathオブジェクトが指すファイルに対して組み込み関数open()と同じ処理が可能。

引数mode'w'とすると書き込みモード。存在しないファイルを指すパスでは新規作成となる。

p_new = Path('temp/new_file.txt')

print(p_new.exists())
# False

with p_new.open(mode='w') as f:
    f.write('line 1\nline 2\nline 3')

引数mode'r'とすると読み込みモード。デフォルトがmode='r'なので省略可能。

with p_new.open() as f:
    print(f.read())
# line 1
# line 2
# line 3

openしたあとの処理はPathopen()メソッドも組み込み関数open()と同じ。

ファイルオブジェクトのwrite()read(), writelines(), readlines()メソッドや追記モードなどの詳細は、組み込み関数open()についての以下の記事を参照。

テキストファイルやバイナリファイルの全体を読み書きするのであれば、次に説明するPathread_text(), write_text(), read_bytes(), write_bytes()メソッドが便利。

テキストファイルの読み込み・書き込み: read_text(), write_text()

Pathread_text()メソッドでテキストファイルの中身全体を文字列として取得可能。

上のopen()メソッドの説明で作成したファイルを読み込んで確認する。

p_new = Path('temp/new_file.txt')

s = p_new.read_text()
print(s)
# line 1
# line 2
# line 3

print(type(s))
# <class 'str'>

書き込みはwrite_text()

書き込んだ文字数が返される。追記ではなく上書きとなり元の内容は削除されるので注意。

i = p_new.write_text('new text')
print(i)
# 8

print(p_new.read_text())
# new text

存在しないファイルの場合、read_text()はエラー。

p_new2 = Path('temp/new_file2.txt')

print(p_new2.exists())
# False

# print(p_new2.read_text())
# FileNotFoundError: [Errno 2] No such file or directory: 'temp/new_file2.txt'

write_text()は新規作成となる。

print(p_new2.write_text('new text2'))
# 9

print(p_new2.read_text())
# new text2

touch()の例と同じく、write_text()で新規作成する場合も直上のディレクトリまでは作成しておかないとエラーとなる。

p_text_new_dir = Path('temp/new_dir2/new_file.txt')

# print(p_text_new_dir.write_text('new_text'))
# FileNotFoundError: [Errno 2] No such file or directory: 'temp/new_dir2/new_file.txt'

直上のディレクトリまで作成する方法はtouch()のところで説明した通り。親ディレクトリのPathオブジェクトをparent属性で取得してmkdir()でディレクトリを作成してからwrite_text()を実行する。

p_text_new_dir.parent.mkdir(parents=True, exist_ok=True)
print(p_text_new_dir.write_text('new_text'))
# 8

print(p_text_new_dir.read_text())
# new_text

直上のディレクトリまで存在している場合は以下のように一行で書ける。

print(Path('temp/new_file3.txt').write_text('new_text3'))
# 9

print(Path('temp/new_file3.txt').read_text())
# new_text3

ファイルの中身を一行ずつ読み込んだり、追記したりする必要がなければopen()よりもread_text(), write_text()のほうが簡単。

バイナリファイルの読み込み・書き込み: read_bytes(), write_bytes()

read_text(), write_text()のバイナリ版がread_bytes(), write_bytes()

使い方はread_text(), write_text()と同じ。バイト列(bytes)を読み書きできる。

p_bin = Path('temp/new_file.bin')

print(p_bin.write_bytes(b'binary'))
# 6

print(p_bin.read_bytes())
# b'binary'

ファイルの削除はunlink()

p_empty = Path('temp/empty_file.txt')

print(p_empty.exists())
# True

p_empty.unlink()

print(p_empty.exists())
# False

デフォルトでは存在しないファイルに対してはエラー。

# p_empty.unlink()
# FileNotFoundError: [Errno 2] No such file or directory: 'temp/empty_file.txt'

Python 3.8でmissing_ok引数が追加された。missing_ok=Trueとすると存在しないファイルでもエラーにならない。

p_empty.unlink(missing_ok=True)

unlink()で削除できるのはファイルとシンボリックリンク。ディレクトリを指すPathオブジェクトではエラーとなる。

p_dir = Path('temp/')

# p_dir.unlink()
# PermissionError: [Errno 1] Operation not permitted: 'temp'

pathlibでのディレクトリの削除については以下の記事を参照。

一覧からすべてのファイルを削除

ディレクトリを示すPathオブジェクトでiterdir()メソッドを使うと、直下のファイル・ディレクトリのPathオブジェクト一覧のイテレータが取得できる。

これを利用してディレクトリ直下のファイルをすべて削除できる。上述のようにunlink()はディレクトリに対してはエラーとなるのでis_file()で場合分けしている。

p_dir = Path('temp/')

for p in p_dir.iterdir():
    if p.is_file():
        p.unlink()

リスト内包表記を利用して一行で書くと以下のようになる。

[p.unlink() for p in p_dir.iterdir() if p.is_file()]

iterdir()ではなくglob()を使うとファイル名やディレクトリ名をワイルドカード文字などの条件で抽出した一覧を取得可能。これに対して上述のようにunlink()を適用すると条件を満たすファイルのみを削除できる。

pathlibでのファイル一覧の取得は以下の記事を参照。

関連カテゴリー

関連記事