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

Python显式设置权限后仍无法删除Windows文件问题排查

问题根因
  • 权限修改逻辑完全无效:你仅对resources根目录调用了os.chmod,没有递归处理目录下的所有文件;且Python的os.chmod在Windows平台仅支持设置stat.S_IWRITE对应的只读标记,你传入的其余POSIX权限位(读、执行、用户组权限等)在NTFS系统下会被直接忽略,这就是你递归调用chmod也看不到权限变化的根本原因。
  • 缺少短暂占用重试逻辑:你确认进程释放了dll句柄,但刚写入磁盘的dll会被Windows Defender等杀毒软件做实时扫描、系统文件缓存也会短暂持有句柄,这个占用窗口通常只有几百毫秒。你手动删除时Windows资源管理器自带隐式重试,等占用释放后就删掉了,但unittest的tearDownClass是用例执行完立刻触发删除,刚好撞上占用窗口,直接抛错。
  • 默认删除逻辑无容错:Python 3.9的shutil.rmtree默认采用_rmtree_unsafe实现,遇到只读文件、短暂占用的文件会直接抛出错误,没有任何重试、权限修正逻辑。
修复方案
  • 给shutil.rmtree传入onerror回调,遇到删除错误时先移除目标文件/目录的只读属性,再重试操作。
  • 给删除流程加显式重试,遇到权限错误时等待几百毫秒后再次尝试,覆盖系统/杀软短暂占用的场景。
  • 优先使用标准库的tempfile.TemporaryDirectory管理临时解压目录,它已经封装了Windows平台下的所有清理兼容逻辑,不需要自己手写路径维护、权限处理代码。

修正后的清理代码如下:

import os
import stat
import time
import shutil

def _handle_remove_error(func, path, exc_info):
    # 移除目标的只读属性
    os.chmod(path, stat.S_IWRITE)
    # 等待短暂占用释放
    time.sleep(0.2)
    # 重试删除操作
    func(path)

class Check():
    def __init__(self, file_path, unzip_dir=None):
        self.file_path = file_path
        self.unzip_dir = unzip_dir

    def terminate(self):
        if self.unzip_dir is None:
            return
        # 最多重试3次,覆盖短暂占用场景
        for _ in range(3):
            try:
                shutil.rmtree(self.unzip_dir, onerror=_handle_remove_error)
                return
            except PermissionError:
                time.sleep(0.5)
        # 重试全部失败再抛出错误
        shutil.rmtree(self.unzip_dir, ignore_errors=False)

如果改用标准库临时目录管理,代码可以更简洁,不需要自己写清理逻辑:

import tempfile
import zipfile

# 临时目录会在with块退出时自动清理,自带Windows平台兼容逻辑
with tempfile.TemporaryDirectory() as unzip_dir:
    # 解压压缩包到临时目录
    with zipfile.ZipFile(self.file_path, 'r') as archive:
        archive.extractall(unzip_dir)
    # 所有依赖解压文件的测试逻辑都写在with块内即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 08:42:28