Python 2.7中的tempfile.TemporaryDirectory上下文管理器

51

在Python 2.7中,是否有一种方法可以使用上下文管理器创建一个临时目录?

with tempfile.TemporaryDirectory() as temp_dir:
    # modify files in this dir

# here the temporary diretory does not exist any more.

请参考 https://dev59.com/fmw15IYBdhLWcg3wA3CT 了解如何手动完成此操作。 - Nils von Barth
2个回答

44

另一个选择是pypi上的"backports.tempfile"包:https://pypi.python.org/pypi/backports.tempfile

引用该项目的描述:"此软件包在backports命名空间下提供Python tempfile模块中新功能的后备。"

安装方法:

pip install backports.tempfile

然后在您的脚本中使用它:

from backports import tempfile
with tempfile.TemporaryDirectory() as temp_dir:
    # modify files in this dir
# here the temporary directory does not exist any more.

我更喜欢这种方式,而不是复制粘贴代码片段。谢谢。希望我的问题不会被关闭,因为我更喜欢使用库。关于库的问题应该去http://softwarerecs.stackexchange.com/...顺便说一句:我在开玩笑,我不明白为什么需要软件推荐网站。为什么不在StackOverFlow上问有关软件推荐的问题呢? - guettli
2
令人烦恼的是,回溯并没有为所有现有的“tempfile”事物设置别名,因此您可能需要同时拥有两者。 - Nick T

34

tempfile.TemporaryDirectory() 是 Python 3.2 中添加到 tempfile 标准库中的。

它是 tempfile.mkdtemp 的简单包装器。它使用纯 Python 编写,可以轻松移植到 Python 2.7。

例如:

from __future__ import print_function

import warnings as _warnings
import os as _os

from tempfile import mkdtemp

class TemporaryDirectory(object):
    """Create and return a temporary directory.  This has the same
    behavior as mkdtemp but can be used as a context manager.  For
    example:

        with TemporaryDirectory() as tmpdir:
            ...

    Upon exiting the context, the directory and everything contained
    in it are removed.
    """

    def __init__(self, suffix="", prefix="tmp", dir=None):
        self._closed = False
        self.name = None # Handle mkdtemp raising an exception
        self.name = mkdtemp(suffix, prefix, dir)

    def __repr__(self):
        return "<{} {!r}>".format(self.__class__.__name__, self.name)

    def __enter__(self):
        return self.name

    def cleanup(self, _warn=False):
        if self.name and not self._closed:
            try:
                self._rmtree(self.name)
            except (TypeError, AttributeError) as ex:
                # Issue #10188: Emit a warning on stderr
                # if the directory could not be cleaned
                # up due to missing globals
                if "None" not in str(ex):
                    raise
                print("ERROR: {!r} while cleaning up {!r}".format(ex, self,),
                      file=_sys.stderr)
                return
            self._closed = True
            if _warn:
                self._warn("Implicitly cleaning up {!r}".format(self),
                           ResourceWarning)

    def __exit__(self, exc, value, tb):
        self.cleanup()

    def __del__(self):
        # Issue a ResourceWarning if implicit cleanup needed
        self.cleanup(_warn=True)

    # XXX (ncoghlan): The following code attempts to make
    # this class tolerant of the module nulling out process
    # that happens during CPython interpreter shutdown
    # Alas, it doesn't actually manage it. See issue #10188
    _listdir = staticmethod(_os.listdir)
    _path_join = staticmethod(_os.path.join)
    _isdir = staticmethod(_os.path.isdir)
    _islink = staticmethod(_os.path.islink)
    _remove = staticmethod(_os.remove)
    _rmdir = staticmethod(_os.rmdir)
    _warn = _warnings.warn

    def _rmtree(self, path):
        # Essentially a stripped down version of shutil.rmtree.  We can't
        # use globals because they may be None'ed out at shutdown.
        for name in self._listdir(path):
            fullname = self._path_join(path, name)
            try:
                isdir = self._isdir(fullname) and not self._islink(fullname)
            except OSError:
                isdir = False
            if isdir:
                self._rmtree(fullname)
            else:
                try:
                    self._remove(fullname)
                except OSError:
                    pass
        try:
            self._rmdir(path)
        except OSError:
            pass

import os
with TemporaryDirectory() as tmp_dir:
    print("Temporary directory path: %s" % tmp_dir)
    print(os.path.isdir(tmp_dir))

# here the temporary diretory does not exist any more.
print(os.path.isdir(tmp_dir))

如果 _<thing> = staticmethod(thing) 行不起作用,也许应该将其删除? - Eli Rose
print(... file=_sys.stderr) 是否缺少 import sys as _sys - hooblei
复杂的代码是由于在最终化期间尝试进行清理,如果上下文管理器在关闭时没有正确关闭。这导致了问题#22427,并已简化。源链接:tempfile.py - Nils von Barth

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接