同じPythonファイルなのに、エディタから実行すると動き、タスクスケジューラからだとファイルが見つからない。こうしたときは、パスの文字列だけでなく、どのフォルダを基準に探しているかを確認します。
pathlib は、ファイルやフォルダのパスを Path オブジェクトで扱う標準ライブラリです。Windowsの区切り文字を手作業でつなげる場面を減らせます。
パスを部品から組み立てる
パスの連結には / を使えます。これは文字列の末尾にスラッシュを足す処理とは違い、パスを組み立てるための演算です。
from pathlib import Path
base = Path(r'C:\work\monthly-report')
input_file = base / 'input' / 'sales.csv'
print(input_file.name)
print(input_file.suffix)
表示されるファイル名は sales.csv、拡張子は .csv です。このコードはパスを作るだけで、ファイルやフォルダは作成しません。C:\work\monthly-report は説明用のWindowsパスなので、自分の保存先へ置き換えます。
相対パスの基準を確かめる
Path('input') のような相対パスは通常、実行時のカレントディレクトリを基準に扱われます。実行しているPythonファイルの保存場所と同じとは限りません。Path.cwd() を表示すると、今の基準を確かめられます。
ファイルとして保存したスクリプトを基準にするなら、Path(__file__).resolve().parent でその場所を求める方法があります。対話環境やノートブックでは __file__ を使えない場合があるため、同じ書き方をそのまま持ち込まないでください。
一時フォルダで読み書きする例
次の例は一時フォルダの中にだけファイルを作ります。処理を抜けると一時フォルダは片付けられるため、保存を続けるためのコードではありません。
from pathlib import Path
from tempfile import TemporaryDirectory
with TemporaryDirectory() as temp_dir:
output = Path(temp_dir) / 'output' / 'memo.txt'
output.parent.mkdir(parents=True, exist_ok=True)
with output.open('x', encoding='utf-8') as stream:
stream.write('集計用のメモ\n')
print(output.name)
print(output.read_text(encoding='utf-8').strip())
出力は memo.txt と「集計用のメモ」の2行です。mkdir() がフォルダを作り、open('x') が新しいファイルを作ります。同名ファイルが既にある場合、x モードは上書きせずエラーになります。
見つからないときに見る場所
exists() で存在を調べるだけでなく、組み立てたパスとカレントディレクトリを確認します。ファイル名、拡張子、共有フォルダへの接続、実行するユーザーの権限も見比べてください。
存在確認の直後に、別の処理がファイルを移すこともあります。事前確認だけで読み書きの成功を保証せず、実際の操作で起きた例外も記録します。loggingの基本と組み合わせると、どの場所で止まったかを追いやすくなります。
CSVを扱う例はPythonのCSV集計へ進めます。各メソッドの仕様はPython公式のpathlibリファレンスで確認してください。
