我有一个python程序使用tempfile.mkdtemp在/ temp下创建tmp目录 不幸的是,python程序在使用后没有删除该目录。所以现在磁盘空间很小。
问题:
答案 0 :(得分:60)
要管理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
如果您使用的是早期版本的Python(至少2.5,那么with
),您可以使用backports.tempfile;请参阅Nicholas Bishop’s answer至tempfile.TemporaryDirectory context manager in Python 2.7。
滚动你自己的课程很简单,也很有教育意义
context manager。 __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)
方法退出上下文 - 即使是异常 - 并执行清理。
@contextlib.contextmanager
您可以使用yield
装饰器简化此操作,因此您无需手动编写上下文管理器。在进入上下文时执行as
之前的代码,生成的值绑定到yield
的目标,并且在退出上下文时执行yield
之后的代码。这基本上是一个coroutine,它封装了资源获取和释放,with
产生控制权限到try...finally
子句的suite(正文)。请注意,这里做需要有一个@contextlib.contextmanager
块,因为yield
没有捕获from contextlib import contextmanager
import tempfile
import shutil
@contextmanager
def TemporaryDirectory():
name = tempfile.mkdtemp()
try:
yield name
finally:
shutil.rmtree(name)
中的异常 - 这只会将资源管理纳入协程
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
正如simplelizz所说,如果您不介意已删除的目录(上述代码假设未发生),您可以按如下方式捕获“无此类文件或目录”例外:
with
您可以与tempfile.py
中的标准实施进行比较;甚至这个简单的课程也有过多年来的错误和演变。
有关{{1}}的背景信息,请参阅:
答案 1 :(得分:28)
阅读documentation,这很简单。 ;)从文档:目录只能通过创建用户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
您也可以尝试tempdir包或查看其来源。
答案 2 :(得分:0)
我认为用户有责任删除使用tempfile.mkdtemp()创建的临时目录及其内容。 它不会像临时文件一样自动删除。 您可以通过多种方式删除目录
如果目录为空,则可以使用
`os.removedirs or os.rmdir`
请注意,只有在目录为空时才能使用
OSError
这将删除整个目录路径:
import shutil
shutil.rmtree('/path/to/your/dir/')
使用此命令时要小心,它将删除其中的整个目录和文件。
答案 3 :(得分:0)
我在使用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()
解决方案适用于Windows 10和Python 3