Pythonで一時ファイルを作成するには、組み込みのtempfileモジュールを使うと便利です。ファイル名が可視化される/されない、使い終わった後に自動で削除される/自分で削除する、など目的に応じて使い分けられるよう関数が用意されています。本記事ではこれらの使い方について、自分にとっての備忘録も兼ねてまとめます。
2019.12.8更新
確認した環境
- Ubuntu16.04LTS
- Python3.7.2
一時ファイルの格納先
一時ファイルの格納先はgettempdir()メソッドで確認出来ます。使っているシステムによって異なるようです。筆者の環境では以下のようになりました。
>>> tempfile.gettempdir()
'/tmp'
(ファイル名見えない)一時ファイルの作成(TemporaryFile)
Tempfile.TemporaryFile()を使います。
このメソッドは一時ファイルとしてfile-like objectを返します。オブジェクトがcloseされると自動的に削除されます。ファイル名は可視化されません。
>>> import tempfile
>>> fp = tempfile.TemporaryFile()
このメソッドのmode 引数のデフォルトは ‘w+b’ です。よって、デフォルトでは書き込みも下記のようにbytes型にする必要があります。
>>> fp.write(b'Test script')
11
データ読み込みはread()メソッドを用いますが、最初にseek(0)でファイルの位置を巻き戻す必要があります。
# seek(0)でファイルの位置を巻き戻し
>>> fp.seek(0)
0
>>> fp.read()
b'Test script'
最後に、close()メソッドでオブジェクトを閉じます。
# 一時ファイルが削除されます。
>>> fp.close()
(ファイル名見える)一時ファイルを作成(NamedTemporaryFile)
NamedTemporaryFile()を使います。
ファイル名が可視化される以外は、TemporaryFile()と同じです。
ファイル名は、生成されたfile-like objectのname属性から確認出来ます。
>>> import tempfile
>>> fp = tempfile.NamedTemporaryFile()
# ファイル名を確認
>>> fp.name
'/tmp/tmp08syj6j7'
# データを書き込み
>>> fp.write(b'test script')
11
# read()だけと読めません
>>> fp.read()
b''
# 読み込みするためには、ファイルの位置を巻き戻す必要あります。
>>> fp.seek(0)
0
>>> fp.read()
b'test script'
# 上記同様、closeするのを忘れずに。
>>> fp.close()
(自動で削除)一時フォルダの作成(TemporaryDirectory)
TemporaryDirectory()を使います。(詳細の引数については公式リファレンスを参照)
一時ファイル作成時の(TemporaryFile()やNamedTemporaryFIle())と同様に、生成されたオブジェクトがcloseされると一時フォルダは自動的に削除されます。
>>> import tempfile
>>> tmpdir = tempfile.TemporaryDirectory()
生成された一時ディレクトリ名は、オブジェクトの name 属性から取得することが出来ます。
# 生成されたディレクトリ名を確認
>>> tmpdir.name
'/tmp/tmpg0pw9bdd'
下記の通り、生成した一時ディレクトへのファイル書き込みも可能です。
>>> fp = open(os.path.join(tmpdir.name, 'testfile'), 'w+b')
>>> fp.write(b'test script')
オブジェクトをcloseさせるには、cleanup()メソッドを使います。
# 最後は下記で閉じるのを忘れずに。
>>> tmpdir.cleanup()
また、コンテキストマネージャ(withステートメント)を使って記述することもできます。下記の例だとファイルがすぐ消えちゃいますが。。。
>>> with tempfile.TemporaryDirectory() as tmpdir:
... with open(os.path.join(tmpdir, 'testfile'), 'w+b') as fp:
... fp.write(b'test script')
...
11
(自分で削除)一時ファイルの作成(mkstemp)
一時ファイルの作成するメソッドとして、mkstemp()もあります。上記のTemporaryFile()と異なるのは、この関数によって生成された一時ファイルは、自分で削除する必要があることです。
返り値は、生成された一時ファイルのファイル記述子fd とファイルの絶対パス名が順番に並んだタプルとなります。
>>> import tempfile
>>> fd, tmpfile = tempfile.mkstemp()
# ファイル記述子と一時ファイルの絶対パスのタプルを返します
>>> fd, tmpfile
(6, '/tmp/tmppjaaloqf')
# 一時ファイルへのデータ書き込み。デフォルトはバイナリモード
>>> with open(tmpfile, 'w+b') as fp:
... fp.write(b'test script')
... 11
# ファイルは自分で削除します
>>> import os
>>> os.remove(tmpfile)
尚、mkstem()関数はtext引数を持っていて、text=Trueとした場合は、ファイルはテキストモードで開きます。(デフォルトはバイナリモード)
# text=Falseを設定
>>> fd, tmpfile = tempfile.mkstemp(text=True)
# テキストモードで書き込み
>>> with open(tmpfile, 'w') as fp:
... fp.write('test script')
... 11
(自分で削除)一時フォルダを作成(mkdtemp)
上記同様に、一時フォルダを作成するメソッドとして、mkdtemp()もあります。
mkstemp()と同様に、不必要になったら自分で削除する必要があります。
返り値は、新たに生成されたディレクトリの絶対パス名となります。
>>> tmpdir = tempfile.mkdtemp()
# 返り値は生成された一時フォルダの絶対パス
>>> tmpdir
'/tmp/tmpr30q43kb'
# 作成した一時フォルダにファイルを作成できます。
>>> with open(os.path.join(tmpdir, 'tmpfile'), 'w+b') as f:
... f.write(b'test script')
... 11
# こちらも自分で削除します。
>>> import shutil
>>> shutil.rmtree(tmpdir)
フォルダの中身ごと削除するにはshutilモジュールを使います。以下の記事でもまとめていますのでご参考。
まとめ
tempfileモジュールを使った一時ファイルを作成する方法についてまとめました。