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

如何在上下文管理器__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

关键说明

  1. 类型校验的必要性:只有OSError及其子类(比如PermissionError、FileNotFoundError这类和系统操作相关的异常)才会携带errno属性。如果直接访问非OSError异常的.errno,会触发AttributeError,所以先通过isinstance(exit_value, OSError)判断类型很重要。
  2. 准确匹配EPERM:errno.EPERM对应系统级的权限不足错误,直接和异常实例的errno属性对比,是最可靠的方式,完全不需要正则匹配这类取巧手段。
  3. 异常分支的逻辑:你可以根据业务需求,给不同的errno值设置不同的处理逻辑,比如遇到文件不存在(errno.ENOENT)时做另一种处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:16:49