note.nkmk.me

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

Date: 2018-10-01 / tags: Python, ファイル操作

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

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

pathlibはPython3.4から追加されたモジュール。ファイルやディレクトリ(フォルダ)のパスをオブジェクトとして操作できる。標準ライブラリに含まれているので追加のインストールは不要(importは必要)。

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

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

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

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

スポンサーリンク

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

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

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_okFalseとすると既存のファイルに対してはエラーとなる。

# 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()と同じ処理が可能。

引数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したあとの処理はPathopen()メソッドも組み込み関数open()と同じ。

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

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

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

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

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

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 = 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()

使い方はread_text(), write_text()と同じ。

read_bytes(), write_bytes()もPython3.5から追加された。

ファイルの削除はunlink()

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

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

スポンサーリンク
シェア
このエントリーをはてなブックマークに追加

関連カテゴリー

関連記事