要在Python中管理资源(如文件),最佳做法是使用
with关键字,自动释放资源(即清除,如关闭文件);这可以从Python 2.5获得。
从Python 3.2,您可以使用tempfile.TemporaryDirectory()而不是tempfile.mkdtmp() – 这是可用于并自动清理目录:
from tempfile import TemporaryDirectory
with TemporaryDirectory() as temp_dir:
# ... do something with temp_dir
# automatically cleaned up when context exited
如果您使用的是较早版本的Python(至少2.5),您可以轻松滚动自己的类,称为a
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之后的代码。这基本上是一个coroutine,它封装了资源的获取和释放,并将收益率控制权转入了条款的suite(正文)。请注意,在这里,您需要尝试… finally块,因为@ contextlib.contextmanager不会在收益中捕获异常 – 这只是将资源管理作为一个协程。
from contextlib import contextmanager
import tempfile
import shutil
@contextmanager
def TemporaryDirectory():
name = tempfile.mkdtemp()
try:
yield name
finally:
shutil.rmtree(name)
as simplylizz指出,如果您不介意已经被删除的目录(上述代码假定不会发生),您可以按如下方式捕获“否这样的文件或目录”异常:
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
有关背景知识,请参阅: