在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. vue导航菜单调用PHP后台数据

    数据库设计: 后台PHP输出所有菜单数据(index.php): <?phpheader("Access-Control-Allow-Origin:*");header(&q ...

  2. 安装k8s-1master多node节点

    卸载比较新的18.3版本,安装17.03版本 删除旧版本 sudo yum remove docker \ docker-client \ docker-client-latest \ docker- ...

  3. js 笔记整理

    Js中for.for-in.forEach以及for-of的用法及特性对比 for-in for...in以任意顺序遍历一个对象的可枚举属性.所以for-in不适合用来迭代一个Array.同时,for ...

  4. SpringBoot简历模板

    项目二:智慧学习-乐勤在线学习网(SpringBoot)◎ 开发模式:团队(8人)                 ◎ 开发周期:4个月◎ 开发环境:JDK1.8.Zookeeper        ◎ ...

  5. 论文阅读 | HotFlip: White-Box Adversarial Examples for Text Classification

    [code] [pdf] 白盒 beam search 基于梯度 字符级

  6. SQL介绍、语句之增删改查大全

    数据库概念 文件作为数据库,数据格式千差万别 将保存数据的地方统一起来 MySQL一款应用软件 用来帮你操作文件的 只要是基于网络通信,底层都是socket!!! 服务端 -socket通信 -收发消 ...

  7. J-流浪西邮之寻找火石碎片 【经典背包变形】

    题目来源:2019 ACM ICPC Xi'an University of Posts & Telecommunications School Contest 链接:https://www. ...

  8. 【转】redis数据库入门教程(全面详细)+面试问题

    [本教程目录] 1.redis是什么2.redis的作者何许人也3.谁在使用redis4.学会安装redis5.学会启动redis6.使用redis客户端7.redis数据结构 – 简介8.redis ...

  9. C++str.Format

    C++应该没有这个函数,说的是Format是在MFC程序里看见的 Format是CString字符串类的成员函数CString::Format( LPCTSTR lpszFormat, ... ); ...

  10. centos7搭建NFS服务

    服务器端 139.155.90.78 客户端  192.168.198.146 先查看自己的系统有没有安装rpcbind 和nfs-utils rpm -qa nfs-utils rpcbind 若使 ...