web-dev-qa-db-ja.com

pythonでtempfile.NamedTemporaryFile()を使用する方法

tempfile.NamedTemporaryFile()を使用して内容を書き込み、そのファイルを開きます。私は次のコードを書きました:

tf = tempfile.NamedTemporaryFile()
tfName = tf.name
tf.seek(0)
tf.write(contents)
tf.flush()

しかし、このファイルを開いてその内容をメモ帳または同様のアプリケーションで見ることができません。これを達成する方法はありますか?なぜ私は次のようなことをすることができません:

os.system('start notepad.exe ' + tfName)

最後に

36
Manoj

これは、次の2つの理由のいずれかです。

まず、デフォルトでは、一時ファイルは 閉じられるとすぐに削除されます です。この使用法を修正するには:

tf = tempfile.NamedTemporaryFile(delete=False)

他のアプリケーションでファイルの表示が終了したら、ファイルを手動で削除します。

または、ファイルがPythonで開いているため、Windowsでは別のアプリケーションを使用して開くことはできません。

46
Dave Webb

また、コンテキストマネージャーで使用して、ファイルが範囲外になったときにファイルを閉じたり削除したりすることもできます。コンテキストマネージャのコードが発生した場合もクリーンアップされます。

import tempfile
with tempfile.NamedTemporaryFile() as temp:
    temp.write('Some data')
    temp.flush()

    # do something interesting with temp before it is destroyed
37
Jay P.

これに役立つコンテキストマネージャを次に示します。 (私の意見では、この機能はPython標準ライブラリの一部である必要があります。)

# python2 or python3
import contextlib
import os

@contextlib.contextmanager
def temporary_filename(suffix=None):
  """Context that introduces a temporary file.

  Creates a temporary file, yields its name, and upon context exit, deletes it.
  (In contrast, tempfile.NamedTemporaryFile() provides a 'file' object and
  deletes the file as soon as that file object is closed, so the temporary file
  cannot be safely re-opened by another library or process.)

  Args:
    suffix: desired filename extension (e.g. '.mp4').

  Yields:
    The name of the temporary file.
  """
  import tempfile
  try:
    f = tempfile.NamedTemporaryFile(suffix=suffix, delete=False)
    tmp_name = f.name
    f.close()
    yield tmp_name
  finally:
    os.unlink(tmp_name)

# Example:
with temporary_filename() as filename:
  os.system('echo Hello >' + filename)
  assert 6 <= os.path.getsize(filename) <= 8  # depending on text EOL
assert not os.path.exists(filename)
0
Hugues