ファイルシステム操作
Pythonプログラムの中からファイルやディレクトリ(フォルダ)を操作する方法について説明します。
実行されるプラットフォームの確認
ファイルを指定するとき、ディレクトリを含めたパス指定で処理する場合では、Windows と Linux ではパスの指定方法が異なっています。
code: Windows の場合
filepath = 'C:\Users\Goichi'
code: Linuxの場合
filepath = '/home/Goichi'
Python の osモジュールはプラットフォームの差異を吸収してくれる便利なモジュールです。
os.name を調べると Python スクリプトが実行されるプラットフォームを知ることができます。
nt: Windows で実行されているとき
posix: Linux系(Bash on Windowsも含む)で実行されているとき
code: 0308_filepath.py
import os
if os.name == 'nt':
filepath = r'C:\Users\Goichi'
else:
filepath = '/home/Goichi'
ファイルやディレクトリの存在チェック
osモジュールのpathクラスを使うと、ファイルもしくはディレクトリが存在しているかをチェックするプログラムを書くことができます。
code: 0309_file_exists.py
import os
filepath = input('Input Filepath: ? ')
print(f'Directory Separator: {os.sep}')
if os.path.exists(filepath): # filepath が存在していれば真
print(f'{filepath} exist.')
if os.path.isfile(filepath): # filepath がファイルなら真
print(f'{filepath} is FILE')
elif os.path.isdir(filepath): # filepath がディレクトリなら真
print(f'{filepath} is DIRECTORY')
else:
print(f'No such file or directory: {filepath}')
プログラム中でのディレクトリセパレータについては、 Windowsでは / も \ も 受け付けるようです。
ディレクトリ操作
ディレクトリ操作では osモジュールの次の関数を呼び出します。
os.getcwd(): 現在の作業ディレクトリのパスを返す
作業ディレクトリはスクリプトが実行されたディレクトリのこと
os.chdir(): 作業ディレクトリを指定したパスに変更する
os.listdir(): 指定したディレクトリパスに存在するファイルやディレクトリを返す
os.mkdir(): 指定した名前のディレクトリを作成
os.makedirs(): 指定したパスで階層的にディレクトリを作成。
途中のディレクトリがなければ作成される
os.rmdir(): 指定した名前のディレクトリを削除
os.removedirs(): 指定したパスのディレクトリを削除。
ディレクトリが空でないとエラーになる。
code: 0310_directory.py
import os
# このスクリプトがあるディレクトリの絶対パス
dirpath = os.path.abspath(os.path.dirname(__file__))
# このスクリプトへの絶対パス
scriptpath = os.path.join(dirpath, __file__)
# 現在の作業ディレクトリを取得
cwd = os.getcwd()
print(f'Current Working Directory: {cwd}')
print(f'Directory path: {dirpath}')
print(f'Script path: {scriptpath}')
testdirpath = os.path.join(dirpath, 'test')
os.mkdir(testdirpath)
__file__ には実行しているスクリプトのファイル名がセットされます。
絶対パスとは、ファイルシステムの最上位の階層からパスを指定したもの。
現在の作業ディレクトリは . 、親ディレクトリは.. で表すこともできます。
Pathlib は便利
ここまではファイル操作の基本です。使いこなしていくなかで、パスの文字列をf-stringやformat()、あるいは演算子(+)でつなげたりと煩雑な処理がでてきます。
そうしたときにとても便利になるのが pathlibモジュールです。
pathlibを使うと記述が簡潔になり読みやすくなります。
pathlib の Pathクラスは PosixPathオブジェクトを返します。
このオブジェクトにはファイル操作に関連する多数のメソッドが提供されています。
code: Ipython
In 1: from pathlib import Path In 2: !touch foo.txt In 3: foo = Path('./foo.txt') In 4: foo Out4: PosixPath('foo.txt') ファイルの存在チェックとは exists()メソッドを呼びます。
code: IPython
In 12: foo.exists() Out12: True アトリビュートname 、suffix、stem を参照すると、ファイル、拡張子、拡張子を除くファイル名が得られます。
code: Python
In 13: foo.name Out13: 'foo.txt' In 14: foo.suffix Out14: '.txt' In 15: foo.stem Out15: 'foo' pathlib の強力な機能のひとつに、パス演算子(/) でパスを生成できることがあります。
code: Python
In 25: !mkdir -p /tmp/a/b/c In 26: tmpdir = Path('/tmp') In 27: savedir = tmpdir / 'a/b/c' In 28: savedir Out28: PosixPath('/tmp/a/b/c') ワイルドカードを使ったファイル指定もglob()メソッドで簡単になります。
code: Python
In 60: !touch /tmp/a/b/c/{a.txt,a.csv,b.txt,b.csv} In 61: !ls /tmp/a/b/c a.csv a.txt b.csv b.txt ファイル名の変更は with_name() を呼び出します。with_suffix()を呼び出すと拡張子を変更することができます。
ただし、ファイル名を変更したPosixPathオブジェクトを返すだけだということに留意してください。実際のファイル名を変更する場合は書き込む必要があります。
code: Python
In 72: file_a = Path(savedir / 'a.csv') In 73: file_a.with_name('sample.csv') Out73: PosixPath('/tmp/a/b/c/sample.csv') In 74: !ls /tmp/a/b/c/ a.csv a.txt b.csv b.txt In 75: file_a.with_suffix('.json') Out75: PosixPath('/tmp/a/b/c/a.json') shutil も便利
ファイル操作を行うときは shutilモジュールを使うと便利になります。
前述の例で変更したファイル名にコピーするときはcopy()を呼び出します。
code: Python
In 76: import shutil In 77: shutil.copyfile(file_a, file_a.with_name('sample.csv')) Out77: PosixPath('/tmp/a/b/c/sample.csv') In 78: !ls /tmp/a/b/c/ a.csv a.txt b.csv b.txt sample.csv move() を使うとディレクトリを移動させたり、ファイル名を変更したりできます。
code: Ipython
In 79: shutil.move('/tmp/a/b/c/sample.csv', '/tmp/a/') Out79: '/tmp/a/sample.csv' 参考: