在python中,如果想手动引发一个异常,我们一般都会使用raise

# -*- coding:utf-8 -*-
# @Author: WanMingZhu
# @Date: 2019/10/22 10:31
try:
1 / 0
except ZeroDivisionError as e:
raise RuntimeError("error occurred")
"""
Traceback (most recent call last):
File "C:/Users/satori/Desktop/satori/task.py", line 5, in <module>
1 / 0
ZeroDivisionError: division by zero During handling of the above exception, another exception occurred: Traceback (most recent call last):
File "C:/Users/satori/Desktop/satori/task.py", line 7, in <module>
raise RuntimeError("error occurred")
RuntimeError: error occurred
"""

如果这样设置异常的话,During handling of the above exception, another exception occurred:,我们只是看到提示:在处理以上异常的时候,另一个异常产生了。如果我们使用raise .....from...的语法呢?

# -*- coding:utf-8 -*-
# @Author: WanMingZhu
# @Date: 2019/10/22 10:31
try:
1 / 0
except ZeroDivisionError as e:
raise RuntimeError("error occurred") from e
"""
Traceback (most recent call last):
File "C:/Users/satori/Desktop/satori/task.py", line 5, in <module>
1 / 0
ZeroDivisionError: division by zero The above exception was the direct cause of the following exception: Traceback (most recent call last):
File "C:/Users/satori/Desktop/satori/task.py", line 7, in <module>
raise RuntimeError("error occurred") from e
RuntimeError: error occurred
"""

The above exception was the direct cause of the following exception:,会直接告诉我们上面异常是下面异常产生的直接原因。

因此我们可以看到两者的不同之处,from会为异常设置一个__cause__属性,表示异常是由谁直接引起的。处理异常的时候出现了新的异常,在不使用from的情况下,更倾向于新异常和旧异常之间没有关联,而from则是能够直接指出新异常是由旧异常直接引起的。这样的话,有助于对异常的分析和排查。但是from有个限制,那就是后面必须跟一个异常的类、或者实例、或者None

# -*- coding:utf-8 -*-
# @Author: WanMingZhu
# @Date: 2019/10/22 10:31
try:
1 / 0
except ZeroDivisionError as e:
raise RuntimeError("error occurred") from 123
"""
raise RuntimeError("error occurred") from 123
TypeError: exception causes must derive from BaseException
"""
# 提示我们必须from一个BaseException
# 这个BaseException是Exception的父类,Exception继承自BaseException
# -*- coding:utf-8 -*-
# @Author: WanMingZhu
# @Date: 2019/10/22 10:31
try:
1 / 0
except ZeroDivisionError as e:
raise RuntimeError("error occurred") from IndexError
"""
raise RuntimeError("error occurred") from 123
TypeError: exception causes must derive from BaseException
"""
# 这里是ZeroDivisionError,我可以手动用IndexError引发

但如果我在finally中引发异常

# -*- coding:utf-8 -*-
# @Author: WanMingZhu
# @Date: 2019/10/22 10:31
try:
1 / 0
except ZeroDivisionError as e:
pass finally:
raise Exception("xxxx")
"""
Traceback (most recent call last):
File "C:/Users/satori/Desktop/satori/task.py", line 10, in <module>
raise Exception("xxxx")
Exception: xxxx
"""

可以看到只出现了我们自己引发的异常,于是我们可以设置一个traceback

# -*- coding:utf-8 -*-
# @Author: WanMingZhu
# @Date: 2019/10/22 10:31
try:
1 / 0
except ZeroDivisionError as e:
import sys
tb = sys.exc_info()[2]
finally:
raise Exception("xxxx").with_traceback(tb)
"""
Traceback (most recent call last):
File "C:/Users/satori/Desktop/satori/task.py", line 10, in <module>
raise Exception("xxxx").with_traceback(tb)
File "C:/Users/satori/Desktop/satori/task.py", line 5, in <module>
1 / 0
Exception: xxxx
"""

通过这种方式,会自动帮我们定位到出现异常的语句。这里trackback就是引发异常语句的异常的trackback

我们目前一直在关联异常,那么可不可以禁止异常关联呢?显然是可以的。

# -*- coding:utf-8 -*-
# @Author: WanMingZhu
# @Date: 2019/10/22 10:31
try:
1 / 0
except ZeroDivisionError as e:
raise Exception("xxxx") from None
"""
Traceback (most recent call last):
File "C:/Users/satori/Desktop/satori/task.py", line 7, in <module>
raise Exception("xxxx") from None
Exception: xxxx
"""

只显示了我们自己定义的异常,没有出现During handling of the above exception, another exception occurred:这样的字眼了。

因此在异常处理中,python会为异常设置上下文。但我们也可以手动通过with_traceback()来设置上下文,或者通过from来指定异常是由谁引起的。这些手段都是为了得到更好的异常回溯信息,打印清晰的异常上下文。若忽略上下文,则可以通过raise ···· from···None来禁止自动显示异常上下文。

raise与raise······from的更多相关文章

  1. raise 与 raise ... from 的区别

    起步 Python 的 raise 和 raise from 之间的区别是什么? try: print(1 / 0) except Exception as exc: raise RuntimeErr ...

  2. python中raise的用法

    有关于python里raise显示引发异常的方法: 当程序出错时,python会自动触发异常,也可以通过raise显示引发异常 一旦执行了raise语句,raise之后的语句不在执行 如果加入了try ...

  3. Python错误调试-raise、assert

    raise: raise语句手工引发一个异常:,这样做程序不会因异常而终止,而是运行报错 1 "raise" [expression ["," expressi ...

  4. python 异常处理函数--raise

    Python 异常处理--raise函数用法 在Python中,要想引发异常,最简单的形式就是输入关键字raise,后跟要引发的异常的名称.异常名称标识出具体的类: Python异常处理是那些类的对象 ...

  5. 信号的发送kill,raise,alarm,setitimer,abort,sigqueue

    1.kill函数 int kill(pid_t pid, int sig); 发送信号给指定的进程. (1) If pid is positive, then signal sig is sent t ...

  6. python 基础 6.2 raise 关键字使用

    一. raise 关键字    raise 用来触发异常    语法如下:     raise[Exception [,args [,traceback]]]     语句中Exception 是异常 ...

  7. python raise a string exception is deprecated

    python不允许raise 一个内建的string 对象.所以就崩溃,可以先将其转换成其他string,比如赋值.

  8. 解决: DeprecationWarning: Passing 1d arrays as data is deprecated in 0.17 and will raise ValueError in 0.19

    错误信息:C:\Python27\lib\site-packages\sklearn\utils\validation.py:395: DeprecationWarning: Passing 1d a ...

  9. ORACLE RAISE

    ORACLE 出错信息的输出 偷懒的办法直接在Exception 后使用raise但是错误信息不是很完整使用RAISE_APPLICATION_ERROR(-20999, DBMS_UTILITY.f ...

随机推荐

  1. 阻塞IO和非阻塞IO的区别

    转载地址: http://blog.sina.com.cn/s/blog_a46817ff0101g0gv.html http://blog.csdn.net/nodeathphoenix/artic ...

  2. 购物车实现 <Block实现回调>

    效果图如下: 具体代码实现如下: Model: #import <Foundation/Foundation.h> @interface ShopCarModel : NSObject @ ...

  3. Python3 Selenium自动化web测试 ==> 第九节 WebDriver高级应用 -- 操作select 和 alert

    学习目的: 掌握页面常规元素的定位方法 场景: 网页正常的select元素下拉框常规方法和select专属方法 正式步骤: step1:常规思路select页面元素定位 处理HTML代码截图 # -* ...

  4. SpringCloud简历模板

    项目三:智慧生鲜(SpringCloud) 开发周期:5个月项目介绍:该项目是一个基于微服分布式的生鲜电商网站,主要模块有前台:用户模块.商品模块.购物车模块.订单模块.支付模块.抢购模块.后台:权限 ...

  5. Leetcode之动态规划(DP)专题-188. 买卖股票的最佳时机 IV(Best Time to Buy and Sell Stock IV)

    Leetcode之动态规划(DP)专题-188. 买卖股票的最佳时机 IV(Best Time to Buy and Sell Stock IV) 股票问题: 121. 买卖股票的最佳时机 122. ...

  6. JavaScript校验身份证,包含省份、长度、出生年月日、校验位的检测、性别、年龄

    一.代码如下 let vcity = {11: '北京', 12: '天津', 13: '河北', 14: '山西', 15: '内蒙古', 21: '辽宁', 22: '吉林', 23: '黑龙江 ...

  7. nginx多线程高并发

    直接上图 Master-Worker模式 1.Nginx 在启动后,会有一个 master 进程和多个相互独立的 worker 进程. 2.接收来自外界的信号,向各worker进程发送信号,每个进程都 ...

  8. 解决mac启动springboot项目很慢的问题

    1.打开终端输入: hostname 查看电脑名称 2.输入命令修改hosts文件 sudo vi /etc/hosts 3. 在127.0.0.1和::1后边分别增加你的电脑名称 127.0.0.1 ...

  9. if(!ConnectDBProc(strCmd,m_dbUserName,m_dbPassword))

    https://wenku.baidu.com/view/826b3d426bec0975f565e204.html

  10. Python与用户的交互

    目录 Python与用户的交互 为什么交互 如何交互 Python2 中的交互 Python与用户的交互 为什么交互 让我们来回顾计算机的发明有何意义,计算机的发明是为了奴役计算机,解放劳动力.假设我 ...