Python tempfile モジュール

一時ファイル(tempfiles)は、主にアプリケーションの中間情報をディスク上に保存するために使用されます。これらのファイルは通常、一時的なバックアップや、アプリケーションがシステムのメモリよりも大きなデータセットを扱う場合など、さまざまな目的のために作成されます。理想的には、これらのファイルは別のディレクトリに配置され、オペレーティングシステムによって異なりますが、これらのファイルの名前は一意です。一時ファイルに保存されたデータは、アプリケーションが終了した後、必ずしも必要ではないので、これらのファイルは使用後に削除されるようにしたい場合があります。

Pythonはtempfileというモジュールを提供し、一時ファイルの作成と取り扱いを容易にしています。このモジュールは、さまざまな方法で一時ファイルやディレクトリを作成するためのメソッドをいくつか提供しています。Python のプログラムでデータを保存するために一時ファイルを使いたいときには、 tempfile が役に立ちます。それでは、 tempfile モジュールがどのように使用されるのか、いくつかの異なる例を見てみましょう。

一時ファイルの作成

例えば、あるファイルを作成し、それを使ってデータを保存し、使用後にそれを削除するようなアプリケーションです。これを実現するには、TemporaryFile() という関数を使います。

この関数は、デフォルトの tempfile という場所にテンポラリファイルを1つ作成します。この場所は、オペレーティングシステムによって異なる場合があります。最も優れている点は、TemporaryFile() によって作成された一時ファイルは、そのファイルを閉じるたびに自動的に削除されることです。また、システムのファイルシステム・テーブルにこのファイルへの参照は作成されません。つまり、他のプログラムはこのファイルを開くことができません。

以下のPythonプログラムを見て、どのように動作するかを見てみましょう。

import tempfile #1


print("Creating one temporary file...")


temp = tempfile.TemporaryFile() #2


try:
    print("Created file is:", temp) #3
    print("Name of the file is:", temp.name) #4
finally:
    print("Closing the temp file")
    temp.close() #5


以下のような出力が表示されます。

$ python3 temp-file.py
Creating one temporary file...
Created file is: <_io.BufferedRandom name=4>
Name of the file is: 4
Closing the temp file


  1. Python で一時ファイルを作成するには、tempfile モジュールをインポートする必要があります。
    1. 上記で説明したように、TemporaryFile()関数を使用して一時ファイルを作成しました。
    1. 出力結果から、作成されたオブジェクトは実際にはファイルではなく、ファイルのようなオブジェクトであることがわかります。また、作成されたファイルの mode パラメータ (この例では表示されていません) は w+b で、つまりクローズされずに読み書きができるようになっています。
    1. 作成された一時ファイルには名前がありません。
  2. 最後に、close()メソッドを使ってファイルをクローズしています。閉じた後は破棄されます。

一つ指摘しておくと、TemporaryFile()関数を使って作成されたファイルは、ファイルシステム上で可視的な名前を持つこともあれば、持たないこともあるということです。Unixでは、ファイルのディレクトリエントリは作成後に自動的に削除されますが、これは他のプラットフォームではサポートされていません。通常、TemporaryFile() は、Pythonのどのプログラムに対しても、一時記憶領域を1つ作成するための理想的な方法です。

名前付きテンポラリーファイルの作成

前の例では、TemporaryFile() 関数を使って作成された一時ファイルは、実際にはファイル名を持たないファイルのようなオブジェクトであることがわかりました。Python は、ファイルシステム上に目に見える名前のファイルを作成するために、 NamedTemporaryFile() という別のメソッドも提供しています。Tempfileに名前を与えること以外は、 NamedTemporaryFile()TemporaryFile() と同じように動作します。では、上の例と同じように、名前付きテンポラリファイルを作成してみましょう。

import tempfile


print("Creating one named temporary file...")


temp = tempfile.NamedTemporaryFile()


try:
    print("Created file is:", temp)
    print("Name of the file is:", temp.name)
finally:
    print("Closing the temp file")
    temp.close()


このコードを実行すると、次のような出力が表示されます。

$ python3 named-temp-file.py
Creating one named temporary file...
Created file is: <tempfile._temporaryfilewrapper 0x103f22ba8="" at="" object="">
Name of the file is: /var/folders/l7/80bx27yx3hx_0_p1_qtjyyd40000gn/T/tmpa3rq8lon
Closing the temp file


このように、作成されたファイルには実際に名前がついています。NamedTemporaryFile()の利点は、作成された一時ファイルの名前を保存しておき、後でそれを閉じたり破壊したりする前に使用することができることです。もしdeleteパラメータをFalse` に設定すれば、ファイルを破壊することなく閉じることができ、後で再び開くことができるようになります。

名前に接尾辞や接頭辞をつけること

テンポラリファイルの名前に接頭辞や接尾辞を付ける必要がある場合があります。これは、プログラムによって作成されたすべての一時ファイルを識別するのに役立ちます。

これを実現するには、上で定義した NamedTemporaryFile 関数を使います。この関数を呼び出す際に追加する必要があるのは、 suffixprefix という 2 つのパラメータだけです。

import tempfile


temp = tempfile.NamedTemporaryFile(prefix="dummyPrefix_", suffix="_dummySuffix")


try:
    print("Created file is:", temp)
    print("Name of the file is:", temp.name)
finally:
    temp.close()


このコードを実行すると、次のような出力が表示されます。

$ python3 prefix-suffix-temp-file.py
Created file is: <tempfile._temporaryfilewrapper 0x102183470="" at="" object="">
Name of the file is: /var/folders/tp/pn3dvz_n7cj7nfs0y2szsk9h0000gn/T/dummyPrefix_uz63brcp_dummySuffix


つまり、 NamedTemporaryFile() 関数に suffixprefix という2つの追加引数を渡すと、ファイル名の先頭と末尾にそれらを自動的に追加してくれます。

一時ファイルからのデータの読み出しと書き込み

これまで、一時ファイルの作成方法、一時ファイルに名前を付ける方法、一時ファイルに接尾辞や接頭辞を付ける方法について学びました。では、実際にPythonでテンポラリファイルからデータを読み書きする方法を理解してみましょう。

Pythonで一時ファイルからデータを読み書きするのはとても簡単です。書き込みには write() メソッドを使い、読み込みには read() メソッドを使います。例えば

import tempfile


print("Current temp directory:", tempfile.gettempdir())


tempfile.tempdir = "/temp"


print("Temp directory after change:", tempfile.gettempdir())


これは b'Hello world!' として出力されます。なぜなら write() メソッドは入力データをバイト単位で受け取るからです (そのため文字列には b というプレフィックスが付いています)。

もし、テキストデータを一時ファイルに書き出したい場合は、代わりに writelines() メソッドを使用することができます。このメソッドを使用するには、デフォルトの w+b モードではなく、 w+t モードを使用して tempfile を作成する必要があります。これを行うには、 TemporaryFile()mode パラメータを渡して、作成する一時ファイルのモードを変更することができます。

$ python3 dir-loc-temp-file.py
Current temp directory: /var/folders/tp/pn3dvz_n7cj7nfs0y2szsk9h0000gn/T
Temp directory after change: /temp


前の例とは異なり、これは出力として “Hello World” を表示します。

一時ディレクトリの作成

プログラムが複数の一時ファイルを持つ場合、一時ディレクトリを一つ作って、その中にすべての一時ファイルを置いた方が便利なことがあります。一時ディレクトリを作成するには、TemporaryDirectory()関数を使用します。すべての一時ファイルを閉じた後、そのディレクトリを手動で削除する必要があります。

import tempfile


temp = tempfile.TemporaryFile()


try:
    temp.write(b'Hello world!')
    temp.seek(0)


print(temp.read())
finally:
    temp.close()


以下のような出力が表示されます。

import tempfile


temp = tempfile.TemporaryFile(mode='w+t')


try:
    temp.writelines("Hello world!")
    temp.seek(0)


print(temp.read())
finally:
    temp.close()


安全なテンポラリーファイルとディレクトリの作成

mkstemp()を利用することで、最も安全な方法で一時ファイルを作成することができます。この方法で作成された一時ファイルは、作成したユーザーIDのみが読み書き可能です。作成されるファイル名にプレフィックスとサフィックスを追加するために、prefixsuffixという引数を渡すことができる。デフォルトでは、ファイルはバイナリモードで開かれる。テキストモードで開くには、関数への引数としてtext=Trueを渡すことができる。TemporaryFile() とは異なり、mkstemp() が作成したファイルは、ファイルを閉じても自動的には削除されません。

以下の例でわかるように、ファイルを削除するのはユーザー側の責任です。

import tempfile


with tempfile.TemporaryDirectory() as tmpdirname:
    print('Created temporary directory:', tmpdirname)


# Both the directory and its contents have been deleted


$ python3 mk-dir-temp-file.py
Created temporary directory: /var/folders/l7/80bx27yx3hx_0_p1_qtjyyd40000gn/T/tmpn_ke7_rk


mkstemp()と同様に、mkdtemp()メソッドを使えば、最も安全な方法で一時ディレクトリを作成することができます。そしてまた、mkstemp()と同様に、ディレクトリ名にプレフィックスとサフィックスを追加するためのprefixsuffix` 引数もサポートしています。

結論

この記事では、Pythonで一時ファイルやディレクトリを作成するさまざまな方法について学びました。一時ファイルはどんなPythonプログラムでも使用することができます。しかし、使用した特定の方法が自動的に削除されない場合は、必ず削除するようにしてください。また、出力ディレクトリ名やファイル名のように、OSによって動作が異なる場合があることも覚えておいてください。

以上説明してきた関数は、いずれもさまざまな引数で動作しますが、それぞれの関数がどのような引数を取るかについては詳しく説明していません。もし、 tempfile モジュールについてもっと知りたいのであれば、Python 3 の公式ドキュメントを参照してください。

</tempfile._temporaryfilewrapper

タイトルとURLをコピーしました