zoukankan      html  css  js  c++  java
  • raise 与 raise ... from 的区别

    起步

    Python 的 raiseraise from 之间的区别是什么?

    
    try:
        print(1 / 0)
    except Exception as exc:
        raise RuntimeError("Something bad happened")
    

    输出:

    
    Traceback (most recent call last):
      File "test4.py", line 2, in <module>
        print(1 / 0)
    ZeroDivisionError: division by zero
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "test4.py", line 4, in <module>
        raise RuntimeError("Something bad happened")
    RuntimeError: Something bad happened
    

    raise from

    
    try:
        print(1 / 0)
    except Exception as exc:
        raise RuntimeError("Something bad happened") from exc
    

    输出:

    
    Traceback (most recent call last):
      File "test4.py", line 2, in <module>
        print(1 / 0)
    ZeroDivisionError: division by zero
    
    The above exception was the direct cause of the following exception:
    
    Traceback (most recent call last):
      File "test4.py", line 4, in <module>
        raise RuntimeError("Something bad happened") from exc
    RuntimeError: Something bad happened
    

    分析

    不同之处在于,from 会为异常对象设置 __cause__ 属性表明异常的是由谁直接引起的。

    处理异常时发生了新的异常,在不使用 from 时更倾向于新异常与正在处理的异常没有关联。而 from 则是能指出新异常是因旧异常直接引起的。这样的异常之间的关联有助于后续对异常的分析和排查。from 语法会有个限制,就是第二个表达式必须是另一个异常类或实例。

    如果在异常处理程序或 finally 块中引发异常,默认情况下,异常机制会隐式工作会将先前的异常附加为新异常的 __context__ 属性。

    当然,也可以通过 with_traceback() 方法为异常设置上下文 __context__ 属性,这也能在 traceback 更好的显示异常信息。

    
    raise Exception("foo occurred").with_traceback(tracebackobj)
    

    禁止异常关联

    from 还有个特别的用法:raise ... from None ,它通过设置 __suppress_context__ 属性指定来明确禁止异常关联:

    
    try:
        print(1 / 0)
    except Exception as exc:
        raise RuntimeError("Something bad happened") from None
    

    输出:

    
    Traceback (most recent call last):
      File "test4.py", line 4, in <module>
        raise RuntimeError("Something bad happened") from None
    RuntimeError: Something bad happened
    

    总结

    在异常处理程序或 finally 块中引发异常,Python 会为异常设置上下文,可以手动通过 with_traceback() 设置其上下文,或者通过 from 来指定异常因谁引起的。这些手段都是为了得到更友好的异常回溯信息,打印清晰的异常上下文。若要忽略上下文,则可以通过 raise ... from None 来禁止自动显示异常上下文。

    参考

    来源:https://segmentfault.com/a/1190000017332255

  • 相关阅读:
    洛谷-P1427 小鱼的数字游戏
    洛谷-P1047 校门外的树
    洛谷-P1046 陶陶摘苹果
    洛谷-P1980 计数问题
    洛谷-P1424 小鱼的航程(改进版)
    洛谷-P1423 小玉在游泳
    洛谷-P1035 级数求和
    洛谷-P1008 三连击
    Oracle 11g r2 rac +openfiler 2.99 安装
    26 主备库并行复制策略
  • 原文地址:https://www.cnblogs.com/qixidi/p/10160614.html
Copyright © 2011-2022 走看看