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

Pythonのpathlibモジュールを使ってファイルを新規作成したり読み込み・書き込みを行ったり削除したりする方法について説明します。 pathlibで扱うPathオブジェクトにはopen()メソッドがあり、組み込み関数open()と同様の処理ができます。また、テキストファイルやバイナリファイルを読み書きするためのread_text(), write_text(), read_bytes(), write_bytes()という非常に便利なメソッドもあります。 pathlibはPython3.4から追加されたモジュール。ファイルやディレクトリ(フォルダ)のパスをオブジェクトとして操作できます。標準ライブラリに含まれているので追加のインストールは不要(importは必要)。

pathlib --- オブジェクト指向のファイルシステムパス — Python 3.7.1rc1 ドキュメント

ここでは以下の内容について説明します。

空のファイルを作成、既存ファイルの日時更新: touch() ファイルのopen: open() テキストファイルの読み込み・書き込み: read_text(), write_text() バイナリファイルの読み込み・書き込み: read_bytes(), write_bytes() ファイルを削除: unlink() 一覧からすべてのファイルを削除組み込み関数open()についての詳細は

pathlibの基礎、ディレクトリの処理については

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

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

pathlib - touch() --- オブジェクト指向のファイルシステムパス — Python 3.7.1rc1 ドキュメント

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

import pathlib
import os

os.makedirs('temp', exist_ok=True)

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

print(p_empty)
# temp/empty_file.txt

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

Pathの基本については

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

print(p_empty.exists())
# False

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

p_empty.touch()

print(p_empty.exists())
# True

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

p_empty.touch()

引数exist_okをFalseとすると既存のファイルに対してはエラーとなります。

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

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

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

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

p_empty_new = pathlib.Path('temp/new_dir/empty_file.txt')
p_empty_new.parent.mkdir(parents=True, exist_ok=True)
p_empty_new.touch()

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

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

ファイルのopen: open()

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

pathlib - open() --- オブジェクト指向のファイルシステムパス — Python 3.7.1rc1 ドキュメント

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

p_new = pathlib.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したあとの処理はPathのopen()メソッドも組み込み関数open()と同じ。 ファイルオブジェクトのメソッドwrite()やread(), writelines(), readlines()や追記モードなどの詳細は、組み込み関数open()についての

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

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

Pathのメソッドread_text()でテキストファイルの中身全体を文字列として取得できます。

pathlib - read_text() --- オブジェクト指向のファイルシステムパス — Python 3.7.1rc1 ドキュメント

open()メソッドで作成したファイルの中身を読み込んで確認します。

s = p_new.read_text()

print(s)
# line 1
# line 2
# line 3

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

書き込みはwrite_text()。

pathlib - write_text() --- オブジェクト指向のファイルシステムパス — Python 3.7.1rc1 ドキュメント

書き込んだ文字数が返されます。追記ではなく上書きとなり元の内容は削除されるので気をつけてください。

i = p_new.write_text('new text')

print(i)
# 8

print(p_new.read_text())
# new text

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

p_new2 = pathlib.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()で新規作成する場合も直上のディレクトリまでは作成しておかないとエラーとなります。

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

直上のディレクトリまで作成する方法はtouch()のところで説明した通り。

p_text_new = pathlib.Path('temp/new_dir2/new_file.txt')
p_text_new.parent.mkdir(parents=True, exist_ok=True)
print(p_text_new.write_text('new_text'))
# 8

print(p_text_new.read_text())
# new_text

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

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

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

一行ずつ読み込んだり、追記したりする必要がなければopen()よりもread_text(), write_text()のほうがはるかに楽。 pathlibモジュールはPython3.4から追加されたが、read_text(), write_text()はPython3.5から追加されたメソッド。バージョンに気をつけてください。

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

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

pathlib - read_bytes() --- オブジェクト指向のファイルシステムパス — Python 3.7.1rc1 ドキュメント pathlib - write_bytes() --- オブジェクト指向のファイルシステムパス — Python 3.7.1rc1 ドキュメント

使い方はread_text(), write_text()と同じ。 read_bytes(), write_bytes()もPython3.5から追加されました。

ファイルの削除はunlink()。

pathlib - unlink() --- オブジェクト指向のファイルシステムパス — Python 3.7.1rc1 ドキュメント

p_empty = pathlib.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'

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

p_dir = pathlib.Path('temp/')

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

pathlibでのディレクトリの削除は

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

ディレクトリを示すPathオブジェクトでiterdir()メソッドを使うと、直下のファイル・ディレクトリのPathオブジェクト一覧のイテレータが取得できます。 これを利用してディレクトリ直下のファイルをすべて削除できます。上述のようにunlink()はディレクトリに対してはエラーとなるのでis_file()で場合分けしています。

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()を適用すると条件を満たすファイルのみを削除することができます。

Last Updated: 6/26/2019, 10:34:03 PM