python 如何删除用tempfile.mkdtemp创建的目录?

sauutmhj  于 2023-01-08  发布在  Python
关注(0)|答案(5)|浏览(244)

我有一个python程序,使用tempfile.mkdtemp/temp下创建临时目录,可惜python程序使用后并没有删除该目录,所以现在磁盘空间不足。
问题:
1.如何手动删除/temp下的临时目录?我尝试手动删除它们,但出现"权限被拒绝"错误。
1.在Python程序中,如何在使用完temp目录后删除它们?

zsohkypk

zsohkypk1#

要在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 answertempfile.TemporaryDirectory context manager in 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)

使用@contextlib.contextmanager装饰器可以简化这个过程,这样就不需要手工编写上下文管理器,进入上下文时执行yield之前的代码,生成的值绑定到as的目标。yield之后的代码在退出上下文时执行,这基本上是一个coroutine,封装了资源的获取和释放。yield将控制权交给了with子句的suite(主体)。注意,这里您 * 不 * 需要有一个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)

正如simplylizz所指出的,如果你不介意目录已经被删除(上面的代码假设不会发生),你可以捕获“No such file or directory”异常,如下所示:

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

您可以与tempfile.py中的标准实现进行比较;即使是这个简单的类也有缺陷,并且经过了多年的发展。
有关with的背景信息,请参见:

4ktjp1zp

4ktjp1zp2#

读一下文献资料,很简单。)从文档中:该目录只能由创建用户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软件包或查看其源代码。

0h4hbjxa

0h4hbjxa3#

我在使用TemporaryDirectory()时遇到过相同/类似的问题,它基本上涵盖了您上面定义的功能。
我的问题是由于临时目录的使用,我曾经通过克隆一个git仓库来填充内容,但在这个过程中碰巧创建了一些只读文件,而在正常退出时,这些只读临时文件会导致整个临时目录停留在那里。
我确实将TemporaryDirectory继承到了我自己的类中,并且确实用下面的代码覆盖了类method _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

uajslkp6

uajslkp64#

我认为用户有责任删除临时文件.mkdtemp()创建的临时目录及其内容。它不会像临时文件一样自动删除。有很多方法可以删除目录
如果目录为空,则可以使用

`os.removedirs or os.rmdir`

请注意,仅当目录为空时才能使用它,否则将引发
错误
这将删除整个目录路径:

import shutil    
shutil.rmtree('/path/to/your/dir/')

小心当使用这,它将删除这整个目录和文件里面.

2vuwiymt

2vuwiymt5#

with语句的替代语句可以是:

import tempfile
tmp_dir = tempfile.TemporaryDirectory()
print(tmp_dir.name)
# Your code Here
tmp_dir.cleanup()

相关问题