如何管理临时目录,以确保在程序关闭时删除它?

Jef*_*ner 10 python garbage-collection

我正在使用一个临时目录,我想确保它在程序关闭时被删除(无论程序是否成功).我正在使用tempfile.mkdtemp创建目录并将创建的字符串放入其子类中str删除其__del__命令中的目录:

import shutil
import tempfile

class TempDir(str):
    """ container for temporary directory. 
    Deletes directory when garbage collected/zero references """
    def __del__(self):
        shutil.rmtree(self.__str__(), onerror=my_error_fn)

dbdir = TempDir(tempfile.mkdtemp())
Run Code Online (Sandbox Code Playgroud)

这是我不确定的:如果程序关闭或发生KeyboardInterrupt,Python会自动删除/垃圾收集所有变量吗?如果没有,我怎么能确保该目录被删除?

有关在Python中创建析构函数方法的相关信息.似乎只要TempDir对象不引用任何其他东西,使用__del__它来破坏它应该没问题.

Ned*_*der 18

我不会使用__del__方法,语义不可靠,并且可能会干扰垃圾收集.使用上下文管理器:定义a __enter____exit__方法,并将对象的使用放在with语句中.很明显,它是明确的,它可以毫无顾虑地工作.

或者,制作上下文管理器的另一种方法:

@contextlib.contextmanager
def tempdir(prefix='tmp'):
    """A context manager for creating and then deleting a temporary directory."""
    tmpdir = tempfile.mkdtemp(prefix=prefix)
    try:
        yield tmpdir
    finally:
        shutil.rmtree(tmpdir)
Run Code Online (Sandbox Code Playgroud)

  • 请注意,Python 3.2 添加了“tempfile.TemporaryDirectory()”,它执行与此答案所示相同的操作。对于 3.2 及更新版本,我将使用库模块代码;对于较旧的 Python 版本,我会使用此代码,但我会将函数重命名为 `TemporaryDirectory()` 并记录它与 3.2 代码类似。https://docs.python.org/3/library/tempfile.html (2认同)

小智 8

我需要类似于包测试套件的东西,这依赖于特定(半模拟)文件结构的存在.对于许多测试模块,我并不总是知道将运行哪些测试以及以什么顺序运行,或者测试运行将如何退出.

根据__del__我的经验,在申请出口处使用是不可靠的.使用上下文管理器意味着重写测试文件以确保所有内容都很好地包装.相反,我使用atexit.在<package>.tests.__init__我刚刚添加:

import atexit, shutil, tempfile

test_area = tempfile.mkdtemp()
atexit.register(shutil.rmtree, test_area)
Run Code Online (Sandbox Code Playgroud)

然后Python将shutil.rmtree(test_area)在退出时调用.如果需要,还可以添加错误处理的关键字参数.