当前位置: 首页 > news >正文

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

相关文章:

  • iOS开发之APP内部切换语言
  • Thanos如何让Prometheus更易用?
  • Spring任务调度之Spring-Task
  • P5112 FZOUTSY
  • java B2B2C springmvc mybatis多租户电子商城系统- 路由定位器
  • linux对vxlan的支持
  • Mysql优化
  • 3.1Python的判断选择语句
  • 深度解析ES6通过WeakMap解决内存泄漏问题
  • Redis 和 memcache 简单比较
  • verilog语法实例学习(1)
  • Docker三剑客之docker-machine
  • 正者表达式exec和match
  • Linux操作系统有什么吸引力,在程序员中这么受欢迎!
  • Oracle常用语句
  • 【347天】每日项目总结系列085(2018.01.18)
  • 【编码】-360实习笔试编程题(二)-2016.03.29
  • 2019年如何成为全栈工程师?
  • Android Volley源码解析
  • cookie和session
  • Java 9 被无情抛弃,Java 8 直接升级到 Java 10!!
  • java正则表式的使用
  • overflow: hidden IE7无效
  • Sequelize 中文文档 v4 - Getting started - 入门
  • vue从创建到完整的饿了么(18)购物车详细信息的展示与删除
  • vue自定义指令实现v-tap插件
  • 和 || 运算
  • 聚簇索引和非聚簇索引
  • 漂亮刷新控件-iOS
  • 浅谈web中前端模板引擎的使用
  • 入门级的git使用指北
  • 深度学习入门:10门免费线上课程推荐
  • 适配iPhoneX、iPhoneXs、iPhoneXs Max、iPhoneXr 屏幕尺寸及安全区域
  • 跳前端坑前,先看看这个!!
  • 原创:新手布局福音!微信小程序使用flex的一些基础样式属性(一)
  • linux 淘宝开源监控工具tsar
  • ​ 全球云科技基础设施:亚马逊云科技的海外服务器网络如何演进
  • ​​​​​​​Installing ROS on the Raspberry Pi
  • #我与Java虚拟机的故事#连载19:等我技术变强了,我会去看你的 ​
  • #预处理和函数的对比以及条件编译
  • (Demo分享)利用原生JavaScript-随机数-实现做一个烟花案例
  • (python)数据结构---字典
  • (补)B+树一些思想
  • (二)springcloud实战之config配置中心
  • (一)Dubbo快速入门、介绍、使用
  • (转)自己动手搭建Nginx+memcache+xdebug+php运行环境绿色版 For windows版
  • .net core MVC 通过 Filters 过滤器拦截请求及响应内容
  • .net反编译工具
  • /etc/skel 目录作用
  • [ vulhub漏洞复现篇 ] GhostScript 沙箱绕过(任意命令执行)漏洞CVE-2019-6116
  • [2021ICPC济南 L] Strange Series (Bell 数 多项式exp)
  • [23] 4K4D: Real-Time 4D View Synthesis at 4K Resolution
  • [3D基础]理解计算机3D图形学中的坐标系变换
  • [c#基础]值类型和引用类型的Equals,==的区别
  • [C++]C++基础知识概述