基于属性捕获异常的Python方案:如何捕获指定hresult的com_error
有两种符合Python风格的实现方式,分别适配不同的使用场景,具体如下:
方案1:捕获后判断hresult(适合单次捕获场景)
这是最直观、无额外魔法的原生写法,完全符合Python异常处理的最佳实践:
import pywintypes # 定义目标错误码,可根据需求修改 TARGET_HRESULT = -2146827284 try: # 执行可能抛出com_error的逻辑,比如Excel COM操作 raise pywintypes.com_error( -2147352567, "Exception occurred.", (0, "Microsoft Excel", "Cannot access 'outAddin.xlam'.", "xlmain11.chm", 0, -2146827284), None, ) except pywintypes.com_error as e: if e.hresult == TARGET_HRESULT: # 匹配到指定错误,执行对应处理逻辑 print("捕获到Excel文件访问拒绝错误,已处理") else: # 不匹配的其他com_error重新抛出 raise
方案2:自定义匹配类实现直接捕获(适合多场景复用)
如果需要在代码中多次捕获同一hresult的com_error,可以通过自定义类重载实例检查逻辑,实现直接在except块中捕获,无需重复写判断代码:
from abc import ABCMeta import pywintypes class ExcelAccessDeniedError(pywintypes.com_error, metaclass=ABCMeta): # 绑定要匹配的hresult TARGET_HRESULT = -2146827284 @classmethod def __instancecheck__(cls, instance): # 只要是com_error实例且hresult匹配,就判定为当前类的实例 return ( isinstance(instance, pywintypes.com_error) and getattr(instance, "hresult", None) == cls.TARGET_HRESULT ) # 用法 try: # 执行可能抛错的COM操作 raise pywintypes.com_error( -2147352567, "Exception occurred.", (0, "Microsoft Excel", "Cannot access 'outAddin.xlam'.", "xlmain11.chm", 0, -2146827284), None, ) except ExcelAccessDeniedError: print("捕获到Excel文件访问拒绝错误,已处理")
疑问解答
- 能不能直接定义com_error的自定义子类实现捕获?
如果是你自己的代码主动抛出异常,可以直接定义子类并抛出子类实例,直接捕获即可。但如果是pywin32等第三方库抛出的原生com_error实例,默认不会匹配自定义子类,需要加上上述__instancecheck__逻辑才能直接在except块捕获。 - 能不能通过重载相等运算符实现?
不行。Python的except语句做的是异常类型匹配,不是对异常实例做相等判断,因此重载==运算符无法实现目标需求。
内容的提问来源于stack exchange,提问作者Greedo
相关产品推荐
相关产品推荐

