我有一个python程序使用tempfile.mkdtemp在/ temp下创建tmp目录.
不幸的是,python程序在使用后没有删除该目录.所以现在磁盘空间很小.
问题:
Nil*_*rth 64
要管理Python中的资源(如文件),最佳做法是使用with
关键字,它会自动释放资源(即清理,如关闭文件); 这可以从Python 2.5获得.
从Python 3.2中,您可以使用tempfile.TemporaryDirectory()
而不是tempfile.mkdtmp()
- 这可用于with
并自动清理目录:
from tempfile import TemporaryDirectory
with TemporaryDirectory() as temp_dir:
# ... do something with temp_dir
# automatically cleaned up when context exited
Run Code Online (Sandbox Code Playgroud)
如果您使用的是早期版本的Python(至少2.5,那么with
),您可以使用backports.tempfile ; 看到尼古拉斯主教的回答到tempfile.TemporaryDirectory上下文管理器在Python 2.7.
滚动自己的类(称为上下文管理器)很容易,也很有启发性
.方法的返回值__enter__()
绑定到as
子句的目标,而在__exit__()
退出上下文时调用该方法 - 即使是异常 - 并执行清理.
import shutil
import tempfile
class TemporaryDirectory(object):
"""Context manager for tempfile.mkdtemp() so it's usable with "with" statement."""
def __enter__(self):
self.name = tempfile.mkdtemp()
return self.name
def __exit__(self, exc_type, exc_value, traceback):
shutil.rmtree(self.name)
Run Code Online (Sandbox Code Playgroud)
您可以使用@contextlib.contextmanager
装饰器简化此操作,因此您无需手动编写上下文管理器.yield
在进入上下文时执行之前的代码,将得到的值绑定到目标as
,并yield
在退出上下文时执行代码.这基本上是一个协同封装资源获取和释放的协同程序,对该子句yield
的套件(主体)具有屈服控制with
.请注意,在这里你就需要有一个try...finally
块,如@contextlib.contextmanager
不赶在例外情况yield
-这只是因素资源管理成协程.
from contextlib import contextmanager
import tempfile
import shutil
@contextmanager
def TemporaryDirectory():
name = tempfile.mkdtemp()
try:
yield name
finally:
shutil.rmtree(name)
Run Code Online (Sandbox Code Playgroud)
正如simplelizz所指出的,如果您不介意已经删除的目录(上面的代码假设没有发生),您可以捕获"无此类文件或目录"异常,如下所示:
import errno
# ...
try:
shutil.rmtree(self.name)
except OSError as e:
# Reraise unless ENOENT: No such file or directory
# (ok if directory has already been deleted)
if e.errno != errno.ENOENT:
raise
Run Code Online (Sandbox Code Playgroud)
您可以与标准实施进行比较tempfile.py
; 甚至这个简单的课程也有过多年来的错误和演变.
有关背景信息with
,请参阅:
sim*_*izz 30
阅读文档,很简单.;)从文档:目录只能通过创建用户ID进行读取,写入和搜索.
要删除临时目录,请尝试以下方法:
import errno
import shutil
import tempfile
try:
tmp_dir = tempfile.mkdtemp() # create dir
# ... do something
finally:
try:
shutil.rmtree(tmp_dir) # delete directory
except OSError as exc:
if exc.errno != errno.ENOENT: # ENOENT - no such file or directory
raise # re-raise exception
Run Code Online (Sandbox Code Playgroud)
您也可以尝试tempdir包或查看其来源.
小智 5
我使用 TemporaryDirectory() 遇到了相同/类似的问题,它基本上涵盖了您上面定义的功能。
我的问题是由于临时目录的使用造成的。我曾经通过克隆 git 存储库来填充内容,碰巧在此过程中创建了只读文件,并且正常退出时这些只读临时文件导致完整的临时目录保留在那里。
是否将 TemporaryDirectory 继承到我自己的类,并使用以下代码重写了类方法 _cleanup 。
super() 之前的代码可能会被优化,但对我来说,性能不是问题。
我确实使用了力量并阅读了“ tempfile ”的来源
import tempfile
import shutil
import stat
class myTempDir(tempfile.TemporaryDirectory):
@classmethod
def _cleanup(self,name, warn_message):
for root, dirs, files in os.walk(name):
for fname in files:
full_path = os.path.join(root, fname)
os.chmod(full_path ,stat.S_IWRITE)
super()
Run Code Online (Sandbox Code Playgroud)
解决方案适用于使用 Python 3 的 Windows 10