可以在 try/except 语句中使用带有 onerror 函数的 rmtree 命令吗?

Can a rmtree command with an onerror function be used within a try/except statement?

我一直在尝试找到有关在使用 shutil.rmtree 命令 inside a try/except 语句时如何处理错误处理和传播的答案.我试图找到一个展示这种做法的例子,但一直找不到。所以,我想知道这是否可能。在阅读命令 here 的文档时,我看到它指出:

...to remove a directory tree on Windows where some of the files have their read-only bit set. It uses the onerror callback to clear the readonly bit and reattempt the remove. Any subsequent failure will propagate.

这是否意味着如果在 初始尝试执行 onerror 函数后 onerror 函数发生错误,换句话说onerror 函数没有修复错误,它发生在 shutil.rmtree 再次尝试 运行 时,错误将在主例程中引发(其中 try/except声明是)? "Any subsequent failure will propagate"就是这个意思吗?

我正在尝试确保无论出于何种原因任何 shutil.rmtree 命令失败,都会捕获失败并且代码仍将继续。我有另一个脚本 运行 在这个脚本之后批量 check/correct 错误,这就是为什么我不直接处理错误。我只需要确保此脚本 运行 一直通过。下面的代码是否会按照编写的那样完成此操作,或者我需要更改什么才能完成此操作?

import shutil
import os
import stat

def remove_readonly(func, path, excinfo):
    os.chmod(path, stat.S_IWRITE)
    func(path)

try:
    #os.chmod is used to turn off Read-Only attribute
    os.chmod("Q:/-----.vbs", stat.S_IWRITE)
    #os.remove is used to remove individual files
    os.remove("Q:/-----.vbs")
except:
    pass

#shutil.rmtree is used to remove entire directories
#remove traces of file
try:
    shutil.rmtree("Q:/FolderToRemove1", onerror=remove_readonly)
except:
    pass

try:
    shutil.rmtree("Q:/FolderToRemove2", onerror=remove_readonly)
except:
    pass

try:
    shutil.rmtree("Q:/FolderToRemove3", onerror=remove_readonly)
except:
    pass

try:
    shutil.rmtree("Q:/FolderToRemove4", onerror=remove_readonly)
except:
    pass

try:
    shutil.rmtree("Q:/FolderToRemove5", onerror=remove_readonly)
except:
    pass

try:
    shutil.rmtree("C:/Users/mhill/Desktop/screenshots", onerror=remove_readonly)
except:
    pass

documentation声明onerror引发的异常不会被捕获,因此您必须自己处理。

就您的示例代码而言,空白 except 通常是糟糕的设计。特别是,它还会捕获 KeyboardInterrupt,这肯定不是您的意图。

而是这样的:

for f in ["Q:/FolderToRemove1", "Q:/FolderToRemove2", 
          "Q:/FolderToRemove3", "Q:/FolderToRemove4", 
          "Q:/FolderToRemove5", "C:/Users/mhill/Desktop/screenshots"]:
    try:
        shutil.rmtree(f, onerror=remove_readonly)
    except Exception:
        pass