Python3.3までは、 「あるディレクトリ以下に存在するテキストファイルの一覧を取得して、それぞれを開く」 という処理に、以下の3つのライブラリを使う必要がありました。
しかし、Python3.4以降であれば、これらを すべて 標準ライブラリpathlib
に一任 することができます。
これによって、ファイル操作処理における 書きやすさ・読みやすさが向上 が向上し、それぞれのライブラリの使い方をわざわざ調べる時間や、 ライブラリ間の微妙な仕様の違いに苛まれる心配から解放されます。
今回は、 「..
以下に存在するテキストファイルをすべて取得して、内容を表示したい」 という目標に対して、pathlibを使わない場合、pathlibを使った場合のコードを比較しましょう。 foo/bar
まずは、os.path、glob.glob、openを使った場合のコードを見てみましょう。
import glob
from os.path import join, dirname, abspath
current_dir = dirname(abspath(__file__))
datasets_dir = join(dirname(current_dir), 'datasets', 'foo', 'bar')
file_names = glob.glob(datasets_dir + '/**/*.txt', recursive=True)
for file_name in file_names:
with open(file_name, 'r') as f:
print(f.read())
あなたは、以下のコードを見て、これがどこを指しているのかすぐに分かりますか?
current_dir = dirname(abspath(__file__))
datasets_dir = join(dirname(current_dir), 'datasets', 'foo', 'bar')
普段、私達はディレクトリパスを左から右に読みますし、英語や日本語も左から右に読みます。しかし、joinやdirnameやabspathを使うと、そのコードがどこのパスを示しているのか、左から右にスラスラ読むことはできません。
datasets_dir = join(dirname(current_dir), 'datasets', 'foo', 'bar')
file_names = glob.glob(dir_name + '/**/*.txt', recursive=True)
os.path.joinでは、引数のパスの先頭に/
がありません。さもなくば、絶対パスとして扱われ、全く別の場所を参照してしまいます。
一方、glob.glob
では、引数のパスの先頭に/
を付けています。さもなくば、意図したパスとは異なる場所を参照してしまいます。
よくよく考えてみれば当たり前のことですが、タイプミスやバグを誘発し、面倒です。
from pathlib import Path
current_dir = Path(__file__).resolve()
datasets_dir = current_dir.parent.parent / 'datasets' / 'foo' / 'bar'
file_names = datasets_dir.glob('**/*.txt')
for file_name in file_names:
print(file_name.read_text())
pathlibを用いた場合、普段我々がディレクトリパスを読む時にそうしているように、左から右にディレクトリパスを追うことができます。
datasets_dir = current_dir.parent.parent / 'datasets' / 'foo' / 'bar'
は、「現在のディレクトリの、親の、親の、'datasets'の中の...」と、まさにそのまま左から右にスラスラと読むことができます。また、pathlibでは/
演算子でパスを結合することができます。慣れないと少し気持ちが悪いかもしれませんが、読みやすいことは間違いありません。
file_names = datasets_dir.glob('**/*.txt')
for file_name in file_names:
print(file_name.read_text())
それだけではなく、ファイルの一覧の取得も datasets_dir.glob('**/*.txt')
で一発です。
ファイルもいちいちopenせずにテキストを取得できます。バイナリを取得したい場合はread_bytes()
を利用してください。
他にも、詳しいことはすべて https://docs.python.jp/3/library/pathlib.html に記されています。本当に便利です。こちらもぜひ一度ご覧になってください。