tempfile --- 一時ファイルやディレクトリの作成¶
ソースコード: Lib/tempfile.py
このモジュールは一時ファイルやディレクトリを作成します。
サポートされている全てのプラットフォームで動作します。
TemporaryFile、NamedTemporaryFile、TemporaryDirectory、 SpooledTemporaryFile は自動的に後始末をし、context managers コンテキストマネージャ として使うことの出来る高水準のインターフェイスです。
mkstemp() と mkdtemp() は手動で後始末をしなければならない低水準の関数です。
ユーザが呼び出し可能な全ての関数とコンストラクタは追加の引数を受け取ります。 その引数によって一時ファイルやディレクトリの場所と名前を直接操作することが出来ます。 このモジュールに使用されるファイル名はランダムな文字を含みます。そのためファイルは共有された一時ディレクトリに安全に作成されます。 後方互換性を保つために引数の順序は若干奇妙です。 分かりやすさのためにキーワード引数を使用してください。
このモジュールではユーザが呼び出し可能な以下の項目を定義しています:
- tempfile.TemporaryFile(mode='w+b', buffering=-1, encoding=None, newline=None, suffix=None, prefix=None, dir=None, *, errors=None)¶
一時的な記憶領域として使うことの出来る file-like object を返します。 ファイルは
mkstemp()と同じルールにより安全に作成されます。 オブジェクトは閉じられる (オブジェクトのガベージコレクションによる暗黙的なものも含みます) とすぐに破壊されます。 Unix では、そのファイルのディレクトリエントリは全く作成されないか、ファイル作成後すぐに削除されます。 これは他のプラットフォームではサポートされません。 よって、この関数で作成された一時ファイルがファイルシステムで可視な名前を持つかどうかをコードで当てにすべきではありません。返されたオブジェクトを コンテキストマネージャ として使うことができます (使用例 を参照してください)。 コンテキストの完了やファイルオブジェクトの破壊で、一時ファイルはファイルシステムから削除されます。
作成されたファイルを閉じることなく読み書きできるように、 mode 引数のデフォルトは
'w+b'です。 保存されるデータに関わらず全てのプラットフォーム上で一貫して動作するようにバイナリモードが使用されます。 buffering、encoding、errors、newline は、open()に対する引数として解釈されます。dir、prefix、suffix 引数の意味とデフォルトは
mkstemp()のものと同じです。返されたオブジェクトは、POSIXプラットフォームでは本物のファイルオブジェクトです。 それ以外のプラットフォームでは、
file属性が下層の本物のファイルであるファイル様オブジェクトです。os.O_TMPFILEフラグは、利用可能で動作する場合に用いられます (Linux 固有で、Linux kernel 3.11 以降)。プラットフォームが Posix でも Cygwin でもない場合は、TemporaryFile は NamedTemporaryFile の別名です。
引数
fullpathを指定して 監査イベントtempfile.mkstempを送出します。バージョン 3.5 で変更: 利用可能であれば
os.O_TMPFILEフラグが使用されます。バージョン 3.8 で変更: errors 引数が追加されました。
- tempfile.NamedTemporaryFile(mode='w+b', buffering=-1, encoding=None, newline=None, suffix=None, prefix=None, dir=None, delete=True, *, errors=None, delete_on_close=True)¶
以下の点を除き、
TemporaryFile()と同じように動作します:返されるファイルには、ファイルシステム上で見える名前が必ずあります。
名前付きファイルを管理するために、
TemporaryFile()の引数に delete と delete_on_close を追加しています。 これらは、名前付きファイルを自動で削除するかどうかと、その方法を指定します。
戻り値は常に ファイル類似オブジェクト で、その
file属性が基となる実際のファイルオブジェクトです。 通常のファイルと同じようにwith文で使えます。 一時ファイルの名前は、返されたファイル類似オブジェクトのname属性から取得できます。 Unix ではTemporaryFile()と異なり、ファイルの作成直後にディレクトリエントリが削除されることはありません。delete が真 (デフォルト) で delete_on_close も真 (デフォルト) の場合、ファイルを閉じるとすぐに削除します。 delete が真で delete_on_close が偽の場合は、コンテキストマネージャーを終了するとき、または ファイル類似オブジェクト をファイナライズするときに削除します。 この場合、削除は常に保証されるわけではありません (
object.__del__()を参照)。 delete が偽の場合、delete_on_close の値は無視します。したがって、一時ファイルを閉じた後で、その名前を使って再び開くには、閉じる際に削除しないようにする (delete 引数を偽にする) か、
with文で一時ファイルを作成する場合は delete_on_close 引数を偽にしてください。 後者ではコンテキストマネージャーの終了時に一時ファイルの自動クリーンアップが行われるため、この方法を推奨します。一時ファイルを開いたまま、その名前を使って再び開く場合の動作は次のとおりです:
POSIX では常に再び開けます。
Windows では、次の条件のうち少なくとも 1 つを満たす必要があります:
delete が偽である
追加のオープンが削除アクセスを共有する (例えば、
O_TEMPORARYフラグを指定してos.open()を呼び出す)delete が真で delete_on_close が偽である。 ただし、この場合は、削除アクセスを共有せずに追加で開いたファイル (例えば、組み込み関数
open()で開いたもの) を、コンテキストマネージャーを終了する前に閉じる必要があります。 そうしないと、終了時のos.unlink()呼び出しがPermissionErrorで失敗します。
Windows では、delete_on_close が偽で、ユーザーに削除アクセス権のないディレクトリにファイルを作成した場合、 コンテキストマネージャーの終了時の
os.unlink()呼び出しがPermissionErrorで失敗します。 delete_on_close が真の場合は、ファイルを開く際に削除アクセスを要求し、それが許可されなければ直ちに失敗するため、この問題は起こりません。POSIX では、SIGKILL で突然終了させられたプロセスは、作成した NamedTemporaryFile を自動的に削除できません。 これは POSIX に限った話です。
引数
fullpathを指定して 監査イベントtempfile.mkstempを送出します。バージョン 3.8 で変更: errors 引数が追加されました。
バージョン 3.12 で変更: delete_on_close 引数が追加されました。
- class tempfile.SpooledTemporaryFile(max_size=0, mode='w+b', buffering=-1, encoding=None, newline=None, suffix=None, prefix=None, dir=None, *, errors=None)¶
このクラスはファイルサイズが max_size を超えるかファイルの
fileno()メソッドが呼ばれるまで、データがメモリにスプールされる点以外はTemporaryFile()と正確に同じことを行います。 上記条件を満たすと内容はディスクに書き込まれ、操作はTemporaryFile()と同様に進みます。- rollover()¶
この関数が返すファイルは、追加で1つのメソッド
rollover()を持っています。このメソッドが呼ばれると、(サイズに関係なく)メモリからディスクへのロールオーバーが実行されます。
返されたオブジェクトはファイル様オブジェクトで、その
_file属性は (バイナリかテキスト mode が指定されたかどうかに依存して)io.BytesIOかio.TextIOWrapperオブジェクト、あるいはrollover()が呼ばれたかどうかに依存して本物のファイルオブジェクトになります。 このファイル様オブジェクトは、通常のファイルオブジェクトと同じようにwith文中で使用することが出来ます。バージョン 3.3 で変更: truncate メソッドが size 引数を受け取るようになりました。
バージョン 3.8 で変更: errors 引数が追加されました。
バージョン 3.11 で変更: バイナリとテキストのどちらの mode を指定したかに応じて、抽象基底クラス
io.BufferedIOBaseまたはio.TextIOBaseを完全に実装するようになりました。
- class tempfile.TemporaryDirectory(suffix=None, prefix=None, dir=None, ignore_cleanup_errors=False, *, delete=True)¶
このクラスは
mkdtemp()と同じルールを使用して安全に一時ディレクトリを作成します。返されたオブジェクトは、コンテキストマネージャ として使用することができます (使用例 を参照)。コンテキストの完了や一時ディレクトリオブジェクトを破壊すると、新規作成された一時ディレクトリとその中身はファイルシステムから削除されます。- name¶
ディレクトリ名は返されたオブジェクトの
name属性から取得できます。返されたオブジェクトが コンテキストマネージャ として使用された場合、nameはwith文内のas節のターゲットがあればそれに割り当てられます。
- cleanup()¶
cleanup()メソッドを呼び出して、ディレクトリを明示的にクリーンアップできます。 ignore_cleanup_errors が真の場合、明示的または暗黙のクリーンアップ中に処理されなかった例外 (Windows で開いたファイルを削除する際のPermissionErrorなど) を無視し、残りの項目も削除できる限り削除します。 そうでなければ、クリーンアップが行われた文脈 (cleanup()の呼び出し、コンテキストマネージャーの終了、オブジェクトのガベージコレクション、インタープリタの終了) でエラーを送出します。
delete 引数を使うと、コンテキストの終了時にディレクトリツリーをクリーンアップしないようにできます。 コンテキストマネージャーが終了時の処理を無効にできるのは変わって見えるかもしれませんが、デバッグ中や、ほかのロジックに応じてクリーンアップを行うかどうかを決めたい場合に役立ちます。
警告
クリーンアップ中にディレクトリツリーが変更された場合の安全性は保証されません。 ツリーの外部のファイルのアクセス権やファイルフラグがリセットされることがあります。
shutil.rmtree.avoids_symlink_attacksが偽のシステムでは、クリーンアップ中にシンボリックリンクを操作すると、ツリーの外部のファイルが削除されることがあります。引数
fullpathを指定して 監査イベントtempfile.mkdtempを送出します。Added in version 3.2.
バージョン 3.10 で変更: ignore_cleanup_errors 引数が追加されました。
バージョン 3.12 で変更: delete パラメータが追加されました。
- tempfile.mkstemp(suffix=None, prefix=None, dir=None, text=False)¶
可能な限り最も安全な手段で一時ファイルを生成します。 プラットフォームが
os.open()のos.O_EXCLフラグを正しく実装している限り、ファイルの作成で競合が起こることはありません。 作成したユーザのユーザ ID からのみファイルを読み書き出来ます。 プラットフォームがファイルが実行可能かどうかを示す許可ビットを使用している場合、ファイルは誰からも実行不可です。このファイル記述子は 子プロセスに継承されません。
TemporaryFile()と異なり、mkstemp()の利用者は、ファイル記述子を閉じる処理 (例えばos.close()) と一時ファイルの削除 (例えばos.remove()) を自分で行う必要があります。suffix が
Noneでない場合、ファイル名はその接尾辞で終わります。 そうでない場合、接尾辞はありません。mkstemp()はファイル名と接尾辞の間にドットを追加しません。 必要であれば suffix の先頭につけてください。prefix が
Noneでない場合、ファイル名はその接頭辞で始まります。 そうでない場合、デフォルトの接頭辞が使われます。 必要に応じ、デフォルトはgettempprefix()またはgettempprefixb()の返り値です。dir が
Noneでない場合、ファイルはそのディレクトリ下に作成されます。Noneの場合、デフォルトのディレクトリが使われます。デフォルトのディレクトリはプラットフォームに依存するリストから選ばれますが、アプリケーションのユーザは TMPDIR、TEMP、または TMP 環境変数を設定することでディレクトリの場所を管理することができます。そのため、生成されるファイル名が、os.popen()で外部コマンドにクォーティング無しで渡すことができるなどといった、扱いやすい性質を持つ保証はありません。suffix、prefix、dir のいずれかが
Noneでない場合、それらは同じ型でなければなりません。 bytes の場合、返された名前は str でなはく bytes です。 他の挙動はデフォルトで返り値を bytes に強制的にしたい場合はsuffix=b''を渡してください。text に真を指定した場合は、ファイルはテキストモードで開かれます。そうでない場合(デフォルト)は、ファイルはバイナリモードで開かれます。
mkstemp()は開かれたファイルを扱うための OS レベルのハンドル (os.open()が返すものと同じ) とファイルの絶対パス名が順番に並んだタプルを返します。引数
fullpathを指定して 監査イベントtempfile.mkstempを送出します。バージョン 3.5 で変更: suffix、prefix、dir は bytes の返り値を得るために bytes で渡すことが出来ます。 それ以前は str のみ許されていました。 適切なデフォルト値を使用するよう、suffix と prefix は
Noneを受け入れ、デフォルトにするようになりました。バージョン 3.6 で変更: dir パラメタが path-like object を受け付けるようになりました。
- tempfile.mkdtemp(suffix=None, prefix=None, dir=None)¶
可能な限り安全な方法で一時ディレクトリを作成します。 ディレクトリの生成で競合は発生しません。 ディレクトリを作成したユーザ ID だけが、このディレクトリに対して内容を読み出したり、書き込んだり、検索したりすることができます。
mkdtemp()のユーザは用済みになった時に一時ディレクトリとその中身を削除しなければなりません。prefix, suffix, dir 引数は
mkstemp()関数のものと同じです。mkdtemp()は新たに生成されたディレクトリの絶対パス名を返します。引数
fullpathを指定して 監査イベントtempfile.mkdtempを送出します。バージョン 3.5 で変更: suffix、prefix、dir は bytes の返り値を得るために bytes で渡すことが出来ます。 それ以前は str のみ許されていました。 適切なデフォルト値を使用するよう、suffix と prefix は
Noneを受け入れ、デフォルトにするようになりました。バージョン 3.6 で変更: dir パラメタが path-like object を受け付けるようになりました。
バージョン 3.12 で変更: dir が相対パスでも、
mkdtemp()は常に絶対パスを返すようになりました。
- tempfile.gettempdir()¶
一時ファイルに用いられるディレクトリの名前を返します。 これはモジュール内の全ての関数の dir 引数のデフォルト値を定義します。
Python は呼び出したユーザがファイルを作ることの出来るディレクトリを検索するのに標準的なリストを使用します。 そのリストは:
環境変数
TMPDIRで与えられているディレクトリ名。環境変数
TEMPで与えられているディレクトリ名。環境変数
TMPで与えられているディレクトリ名。プラットフォーム依存の場所:
Windows では
%USERPROFILE%\AppData\Local\Temp、%SYSTEMROOT%\Temp、C:\TEMP、C:\TMP、\TEMP、\TMPの順。その他の全てのプラットフォームでは、
/tmp、/var/tmp、および/usr/tmpの順。
最後の手段として、現在の作業ディレクトリ。
この検索の結果はキャッシュされます。以下の
tempdirの記述を参照してください。バージョン 3.10 で変更: 常に str を返すようになりました。 以前は
tempdirがNoneでなければ、その型を問わず値を返していました。
- tempfile.gettempdirb()¶
gettempdir()と同じですが返り値は bytesです。Added in version 3.5.
- tempfile.gettempprefix()¶
一時ファイルを生成する際に使われるファイル名の接頭辞を返します。 これにはディレクトリ部は含まれません。
- tempfile.gettempprefixb()¶
gettempprefix()と同じですが返り値は bytes です。Added in version 3.5.
このモジュールは、gettempdir() が返す一時ファイル用ディレクトリの名前をグローバル変数に格納します。
直接設定してディレクトリの選択処理を上書きできますが、推奨しません。
このモジュールのすべての関数には、ディレクトリを指定する dir 引数があります。
こちらを使う方法を推奨します。
API 全体の動作を変えずに済むため、その変更を想定していないほかのコードに影響を及ぼしません。
- tempfile.tempdir¶
この変数を
None以外に設定すると、このモジュールの関数の dir 引数のデフォルト値を、bytes または str という型も含めて指定します。 パス類似オブジェクト は指定できません。tempdirが (デフォルトの)Noneの場合、gettempprefix()を除く上記のいずれかの関数を呼び出す際は常にgettempdir()で述べられているアルゴリズムによって初期化されます。
使用例¶
tempfile モジュールの典型的な使い方をいくつか示します。
>>> import tempfile
# 一時ファイルを作成してデータを書き込む
>>> fp = tempfile.TemporaryFile()
>>> fp.write(b'Hello world!')
# ファイルからデータを読み取る
>>> fp.seek(0)
>>> fp.read()
b'Hello world!'
# ファイルを閉じると削除される
>>> fp.close()
# コンテキストマネージャーを使って一時ファイルを作成する
>>> with tempfile.TemporaryFile() as fp:
... fp.write(b'Hello world!')
... fp.seek(0)
... fp.read()
b'Hello world!'
>>>
# ファイルは閉じられ、削除されている
# コンテキストマネージャーを使って一時ファイルを作成する
# ファイルを閉じ、名前を使って再び開く
>>> with tempfile.NamedTemporaryFile(delete_on_close=False) as fp:
... fp.write(b'Hello world!')
... fp.close()
... # ファイルは閉じられているが、削除されていない
... # 名前を使ってファイルを再び開く
... with open(fp.name, mode='rb') as f:
... f.read()
b'Hello world!'
>>>
# ファイルは削除されている
# コンテキストマネージャーを使って一時ディレクトリを作成する
>>> with tempfile.TemporaryDirectory() as tmpdirname:
... print('created temporary directory', tmpdirname)
>>>
# ディレクトリとその内容は削除されている
非推奨の関数と変数¶
一時ファイルを作成する歴史的な手法は、まず mktemp() 関数でファイル名を作り、その名前を使ってファイルを作成するというものでした。
残念ながらこの方法は安全ではありません。
なぜなら、mktemp() の呼び出しと最初のプロセスが続いてファイル作成を試みる間に、異なるプロセスがその名前でファイルを同時に作成するかもしれないからです。
解決策は二つのステップを同時に行い、ファイルをすぐに作成するというものです。
この方法は mkstemp() や上述している他の関数で使用されています。
- tempfile.mktemp(suffix='', prefix='tmp', dir=None)¶
バージョン 2.3 で非推奨: 代わりに
mkstemp()を使って下さい。呼び出し時には存在しなかった、ファイルの絶対パス名を返します。 prefix、suffix、dir 引数は
mkstemp()のものと似ていますが、bytes のファイル名、suffix=None、そしてprefix=Noneがサポートされていない点で異なります。警告
この関数を使うとプログラムのセキュリティホールになる可能性があります。この関数がファイル名を返した後、あなたがそのファイル名を使って次に何かをしようとする段階に至る前に、誰か他の人間があなたを出し抜くことができてしまいます。
mktemp()の利用は、NamedTemporaryFile()にdelete=False引数を渡すことで、簡単に置き換えることができます:>>> f = NamedTemporaryFile(delete=False) >>> f.name '/tmp/tmptjujjt' >>> f.write(b"Hello World!\n") 13 >>> f.close() >>> os.unlink(f.name) >>> os.path.exists(f.name) False