在Python中删除目录中的内容,同时忽略某个模式

后端开发 2026-07-11

shutil库有一个示例,展示如何在复制目录时递归忽略某些内容,使用一个模式:

from shutil import copytree, ignore_patterns

copytree(source, destination, ignore=ignore_patterns('*.pyc', 'tmp*'))

那么你将如何实现同样的功能,只不过要递归删除目录中的内容呢?shutil.rmtree() 存在,但它没有一个像 copytree() 那样的 ignore 参数。

# Would want to do something like this
rmtree(source, destination, ignore=ignore_patterns('donotdeletethis.txt'))

解决方案

最简单的方法是遍历目录内容并使用 fnmatch 进行过滤:

import os
import shutil
import fnmatch

def rmtree_ignore(path, *patterns):
    for item in os.listdir(path):
        # Skip files/folders matching the pattern
        if any(fnmatch.fnmatch(item, pattern) for pattern in patterns):
            continue

        full_path = os.path.join(path, item)
        if os.path.isdir(full_path):
            shutil.rmtree(full_path)
        else:
            os.remove(full_path)

# Usage - same syntax as ignore_patterns
rmtree_ignore('/tmp/my_dir', '*.pyc', 'tmp*')

如果你想保持与 copytree 相同的API,并配合 ignore_patterns 使用,你可以直接复用 shutil.ignore_patterns

import os
import shutil

def rmtree_ignore(path, ignore=None):
    if ignore is None:
        shutil.rmtree(path)
        return

    items = os.listdir(path)
    ignored = ignore(path, items)  # ignore_patterns returns a set of ignored names

    for item in items:
        if item in ignored:
            continue
        full_path = os.path.join(path, item)
        if os.path.isdir(full_path):
            shutil.rmtree(full_path)
        else:
            os.remove(full_path)

# Usage
rmtree_ignore('/tmp/my_dir', ignore=shutil.ignore_patterns('*.pyc', 'tmp*'))

第二种方法更简洁——shutil.ignore_patterns() 返回一个可调用对象,该对象接收 (directory, contents),并返回一个要跳过的名称集合,因此你可以直接复用它,而无需重新实现模式匹配逻辑。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章