如何在上下文管理器__exit__方法中获取异常的errno属性
解决方案:直接访问异常实例的
errno属性 好问题!你已经把上下文管理器的框架搭得很到位了,要获取异常的errno其实非常直接——__exit__方法里的exit_value参数就是触发的异常实例,你可以直接访问它的.errno属性,不过要先做类型校验避免报错。
修改后的代码示例
import errno import sys class Directory: def __init__(self): self._create_backup() # 你的其他初始化逻辑... def __enter__(self): return self def __exit__(self, exit_type, exit_value, exit_traceback): # 首先判断是否有异常发生(exit_type不为None就说明有异常) if exit_type is not None: # 仅针对OSError及其子类(比如PermissionError、FileNotFoundError)处理errno if isinstance(exit_value, OSError): if exit_value.errno == errno.EPERM: print("检测到权限错误(EPERM),正在恢复目录备份...") self._restore_from_backup() # 这里可以添加其他errno的判断逻辑,比如ENOENT等 # 单独处理键盘中断 elif exit_type is KeyboardInterrupt: self._restore_from_backup() sys.exit("Caught system interrupt. Aborting.") # 其他类型异常的通用处理(根据你的需求决定是否恢复备份) else: print(f"发生未知异常:{exit_type.__name__},正在恢复备份...") self._restore_from_backup() else: # 没有异常发生,删除备份 self._delete_backup() def _create_backup(self): # 你的备份逻辑 pass def _restore_from_backup(self): # 你的恢复逻辑 pass def _delete_backup(self): # 你的删除备份逻辑 pass
关键说明
- 类型校验的必要性:只有
OSError及其子类(比如PermissionError、FileNotFoundError这类和系统操作相关的异常)才会携带errno属性。如果直接访问非OSError异常的.errno,会触发AttributeError,所以先通过isinstance(exit_value, OSError)判断类型很重要。 - 准确匹配EPERM:
errno.EPERM对应系统级的权限不足错误,直接和异常实例的errno属性对比,是最可靠的方式,完全不需要正则匹配这类取巧手段。 - 异常分支的逻辑:你可以根据业务需求,给不同的
errno值设置不同的处理逻辑,比如遇到文件不存在(errno.ENOENT)时做另一种处理。
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

