2016-06-24 19 views
0

処理後に条件付きで一時ファイルをクリーンアップするコンテキストマネージャーを作成しようとしています。簡体字:このスクリプトをしようとコンテキストマネージャーで一時ファイルを削除する

import os 
from contextlib import contextmanager 
from subprocess import Popen 
from tempfile import NamedTemporaryFile 


@contextmanager 
def temp(cleanup=True): 
    tmp = NamedTemporaryFile(delete=False) 
    try: 
     yield tmp 
    finally: 
     cleanup and os.remove(tmp.name) 

with temp() as tmp: 
    tmp.write(b'Hi') 
    p = Popen(['cmd', '/c', 'type', tmp.name]) 
    p.wait() 

が発生します

Traceback (most recent call last): 
    File "C:\temp\test.py", line 18, in <module> 
    p.wait() 
    File "C:\Python35\lib\contextlib.py", line 66, in __exit__ 
    next(self.gen) 
    File "C:\temp\test.py", line 13, in temp 
    cleanup and os.remove(tmp.name) 
PermissionError: [WinError 32] The process cannot access the file because it is being used by another process: 'C:\\Temp\\tmp79su99sg' 

私は明らかにそれがないときに一時ファイルは、文のサイクルとの最後で解放されることを期待します。

答えて

1

実際にファイルを削除しようとすると開いています。 あなたはそれを削除する前に、最初のファイルをクローズする必要があります:

@contextmanager 
def temp(cleanup=True): 
    tmp = NamedTemporaryFile(delete=False) 
    try: 
     with tmp: 
      yield tmp 
    finally: 
     cleanup and os.remove(tmp.name) 
+0

ああ素敵:

@contextmanager def temp(cleanup=True): tmp = NamedTemporaryFile(delete=False) try: yield tmp finally: tmp.close() #closes the file, so we can right remove it cleanup and os.remove(tmp.name) 

別のオプションは、コンテキストマネージャとファイル・オブジェクトをラップすることです。ありがとう – vedar

関連する問題