Python decimal模块如何正确捕获DivisionUndefined错误
问题原因
Python decimal 模块的异常抛出逻辑和常规Python异常存在区别:DivisionUndefined属于运算信号类,默认配置下触发该信号时不会直接抛出DivisionUndefined类的实例,而是会被包装为其父类InvalidOperation的异常实例抛出,异常对象的参数中会携带本次触发的具体信号类型集合,因此直接编写except DivisionUndefined分支无法匹配到实际抛出的异常。
正确捕获方案
方案1:捕获父类后校验具体信号类型
该方案不需要修改decimal模块的默认运算配置,不会影响其他位置的decimal运算逻辑,适合仅在当前代码块做细分错误处理的场景:
from decimal import Decimal, DivisionUndefined, InvalidOperation try: Decimal('0') / Decimal('0') except InvalidOperation as e: # 校验触发的异常信号是否包含DivisionUndefined if DivisionUndefined in e.args[0]: print('spam') else: # 非目标场景的InvalidOperation继续向上抛出,避免吞掉其他错误 raise
运行上述代码会正常输出spam。
方案2:修改上下文陷阱规则,直接抛出DivisionUndefined
如果需要在全局/当前上下文内直接捕获DivisionUndefined,可以调整decimal上下文的陷阱配置,开启DivisionUndefined对应的陷阱开关,后续触发该信号时会直接抛出DivisionUndefined实例,不需要再做类型校验:
from decimal import Decimal, DivisionUndefined, getcontext # 开启DivisionUndefined陷阱,触发时直接抛出对应异常 getcontext().traps[DivisionUndefined] = True try: Decimal('0') / Decimal('0') except DivisionUndefined: print('spam')
运行上述代码同样会正常输出spam。
注意:修改上下文traps配置会影响当前上下文内所有后续的decimal运算逻辑,如果仅需要临时生效,可以配合
localcontext()做上下文隔离。
内容的提问来源于stack exchange,提问作者aligen
相关产品推荐
相关产品推荐

