You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中递归删除目录内容时忽略指定模式的实现方法

实现带忽略模式的递归删除目录内容

好问题!确实shutil.rmtree()是用来彻底删除整个目录树的,没有提供类似copytree()那样的ignore参数来跳过特定内容。不过我们可以自己实现这个逻辑,核心思路是遍历目录,选择性删除不匹配忽略模式的内容,甚至可以直接复用shutil.ignore_patterns()来处理模式匹配,不用自己造轮子。

方案一:手动遍历+选择性删除

这个方案最直观,递归遍历目标目录,对每个文件/子目录判断是否需要保留,只删除那些不在忽略列表里的内容。

完整代码实现

import os
from shutil import ignore_patterns

def rmtree_ignore(source_dir, ignore):
    """
    递归删除目录下的内容,但忽略符合指定模式的文件/目录
    :param source_dir: 要处理的目标目录
    :param ignore: 由ignore_patterns()返回的忽略规则函数
    """
    # 遍历目录下的所有条目
    for item in os.listdir(source_dir):
        item_path = os.path.join(source_dir, item)
        
        # 检查当前条目是否在忽略列表中
        ignored_items = ignore(source_dir, [item])
        if item in ignored_items:
            continue  # 跳过,不删除
        
        # 如果是文件或符号链接,直接删除
        if os.path.isfile(item_path) or os.path.islink(item_path):
            os.unlink(item_path)
        # 如果是目录,先递归处理子目录内容,再判断是否删除空目录
        elif os.path.isdir(item_path):
            rmtree_ignore(item_path, ignore)
            # 子目录处理完后如果为空,就删除它
            if not os.listdir(item_path):
                os.rmdir(item_path)

# 示例用法:删除source目录下所有内容,除了donotdeletethis.txt
if __name__ == "__main__":
    source = "/path/to/your/source/dir"
    rmtree_ignore(source, ignore_patterns('donotdeletethis.txt'))

代码说明

  • 复用ignore_patterns():这个函数会帮我们处理通配符匹配(比如*.pyc、tmp*),返回一个可以判断条目是否需要忽略的函数,省去了我们自己写匹配逻辑的麻烦。
  • 递归处理子目录:对于每个子目录,先递归删除其内部的非忽略内容,之后如果子目录变成空目录(没有保留任何内容),就把这个空目录也删掉;如果子目录里还有被忽略的内容,就保留该子目录。
  • 区分文件和目录:文件/符号链接直接删除,目录则先处理内部再决定是否删除自身。

方案二:临时迁移保留内容(适用于删除整个目录但保留部分内容)

如果你需要的是删除整个目录,但把指定内容保留下来,可以先把要保留的内容移到临时目录,删除原目录后再把保留内容移回去:

import os
import shutil
from shutil import ignore_patterns

def rmtree_with_keep(source_dir, keep_patterns):
    # 创建临时目录
    temp_dir = os.path.join(os.path.dirname(source_dir), f"temp_{os.path.basename(source_dir)}")
    os.makedirs(temp_dir, exist_ok=True)
    
    # 复制要保留的内容到临时目录
    shutil.copytree(source_dir, temp_dir, ignore=ignore_patterns(*keep_patterns))
    
    # 删除原目录
    shutil.rmtree(source_dir)
    
    # 把保留的内容移回原位置
    shutil.move(temp_dir, source_dir)

# 示例用法:删除整个source目录,但保留donotdeletethis.txt
if __name__ == "__main__":
    source = "/path/to/your/source/dir"
    rmtree_with_keep(source, ['donotdeletethis.txt'])

注意事项

  • 这个方案适合需要彻底替换目录内容,但保留特定文件的场景,但要注意临时目录的权限问题,以及移动过程中可能出现的异常(比如磁盘空间不足)。
  • 如果目录很大,复制操作会比较耗时,优先选择方案一。

内容的提问来源于stack exchange,提问作者nezzer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 10:02:32