如何从shutil.rmtree的onerror回调中返回log字典
解决方案:不用全局变量获取shutil.rmtree的错误日志
因为shutil.rmtree的onerror回调函数返回值会被忽略,且每次触发错误时都会重新调用回调,直接返回字典的方式无法累积错误记录。要在不使用全局变量的情况下实现错误日志的收集,有两种实用方案:
方案一:使用闭包
通过外层函数维护错误日志的状态,返回内部回调函数和日志字典,内部函数可以直接访问外层的日志变量:
import shutil def create_error_logger(): error_log = {} def error_handler(func, path, excinfo): """处理rmtree删除时的错误,将信息累积到error_log字典""" # 整理错误信息:[错误类名, 错误消息, 触发错误的函数名] error_details = [excinfo[0].__name__, excinfo[1].strerror, func.__name__] error_log[path] = error_details return error_handler, error_log # 使用示例 path_to_remove = r"C:\shutil_test\remove_me" error_handler, error_log = create_error_logger() try: shutil.rmtree(path_to_remove, onerror=error_handler) finally: # 查看错误日志 if error_log: print("删除过程中出现以下错误:") for path, details in error_log.items(): print(f"路径: {path}") print(f"错误类型: {details[0]}, 消息: {details[1]}, 触发函数: {details[2]}") else: print("删除完成,无错误")
方案二:使用类
通过类的实例属性保存错误日志,将实例方法作为onerror的回调函数:
import shutil class ErrorLogger: def __init__(self): self.log = {} def handle_error(self, func, path, excinfo): """处理rmtree删除时的错误,将信息累积到实例的log属性中""" self.log[path] = [excinfo[0].__name__, excinfo[1].strerror, func.__name__] # 使用示例 path_to_remove = r"C:\shutil_test\remove_me" logger = ErrorLogger() try: shutil.rmtree(path_to_remove, onerror=logger.handle_error) finally: if logger.log: print("删除过程中出现以下错误:") for path, details in logger.log.items(): print(f"路径: {path}") print(f"错误类型: {details[0]}, 消息: {details[1]}, 触发函数: {details[2]}") else: print("删除完成,无错误")
原代码的问题说明
你原来的_error_log函数每次被调用时都会新建一个空的log字典,且shutil.rmtree不会处理回调的返回值,因此无法获取到任何错误记录。上面两种方案通过让回调函数共享同一个存储结构(闭包的外层变量或类实例的属性),实现了无全局变量的错误日志累积。
内容的提问来源于stack exchange,提问作者DarKing
相关产品推荐
相关产品推荐

