编写代码时能否手动抛出一个异常吗?答案是肯定的,Python 允许程序自行引发异常,使用 raise 语句即可。基本语法格式为:raise [exceptionName [(reason)]]

其中,用 [] 括起来的为可选参数,其作用是指定抛出的异常名称,以及异常信息的相关描述。如果可选参数全部省略,则 raise 会把当前错误原样抛出;如果仅省略 (reason),则在抛出异常时,将不附带任何的异常描述信息。

也就是说,raise 语句有如下三种常用的用法:

1、raise:单独一个 raise。该语句引发当前上下文中捕获的异常(比如在 except 块中),或默认引发 RuntimeError 异常。

2、raise 异常类名称:raise 后带一个异常类名称。该语句引发指定异常类的默认实例。

3、raise 异常类名称(描述信息):在引发指定异常的同时,附带异常的描述信息。

上面三种用法最终都是要引发一个异常实例(即使指定的是异常类,实际上也是引发该类的默认实例),raise 语句每次只能引发一个异常实例。

例如:>>> raise

Traceback (most recent call last):

File "", line 1, in

raise

RuntimeError: No active exception to reraise

>>> raise ZeroDivisionError

Traceback (most recent call last):

File "", line 1, in

raise ZeroDivisionError

ZeroDivisionError

>>> raise ZeroDivisionError("除数不能为零")

Traceback (most recent call last):

File "", line 1, in

raise ZeroDivisionError("除数不能为零")

ZeroDivisionError: 除数不能为零

注意,即使是用户自行引发的异常,也可以使用 try except 来捕获它。当然也可以不管它,让该异常向上(先调用者)传播,如果该异常传到 Python 解释器,那么程序就会中止。

下面示例示范了处理用户引发异常的两种方式:def main():

try:

# 使用try...except来捕捉异常

# 此时即使程序出现异常,也不会传播给main函数

mtd(3)

except Exception as e:

print('程序出现异常:', e)

# 不使用try...except捕捉异常,异常会传播出来导致程序中止

mtd(3)

def mtd(a):

if a > 0:

raise ValueError("a的值大于0,不符合要求")

main()

从上面程序可以看到,程序既可在调用 mtd(3) 时使用 try except 来捕获异常,这样该异常将会被 except 块捕获;也可直接调用 mtd(3),这样该函数的异常就会直接导致程序中止。

运行上面程序,可以看到如下输出结果:

程序出现异常: a的值大于0,不符合要求Traceback (most recent call last):

File "C:UsersmengmaDesktop1.py", line 13, in

main()

File "C:UsersmengmaDesktop1.py", line 9, in main

mtd(3)

File "C:UsersmengmaDesktop1.py", line 12, in mtd

raise ValueError("a的值大于0,不符合要求")

ValueError: a的值大于0,不符合要求

上面第一行输出是第一次调用 mtd (3) 的结果,该方法引发的异常被 except 块捕获并处理。后面的大段输出则是第二次调用 mtd(3) 的结果,由于该异常没有被 except 块捕获,导致程序中止。

第二次调用 mtd(3) 引发的以“File”开头的三行输出,其实显示的就是异常的传播轨迹信息。也就是说,如果程序不对异常进行处理,Python 默认会在控制台输出异常的传播轨迹信息。

raise 不需要参数

正如前面所看到的,在使用 raise 语句时可以不带参数,此时 raise 语句处于 except 块中,它将会自动引发当前上下文激活的异常;否则,通常默认引发 RuntimeError 异常。

例如,将上面程序改为如下形式:class AuctionException(Exception): pass

class AuctionTest:

def __init__(self, init_price):

self.init_price = init_price

def bid(self, bid_price):

d = 0.0

try:

d = float(bid_price)

except Exception as e:

# 此处只是简单地打印异常信息

print("转换出异常:", e)

# 再次引发自定义异常

raise

if self.init_price > d:

raise AuctionException("竞拍价比起拍价低,不允许竞拍!")

initPrice = d

def main():

at = AuctionTest(20.4)

try:

at.bid("df")

except AuctionException as ae:

# 再次捕获到bid()方法中的异常,并对该异常进行处理

print('main函数捕捉的异常:', ae)

main()

正如从 13 行代码所看到的,此时程序在 except 块中只是简单地使用 raise 语句来引发异常,那么该 raise 语句将会再次引发该 except 块所捕获的异常。运行该程序,可以看到如下输出结果:转换出异常: could not convert string to float: 'df'

main 函数捕获的异常:

从输出结果来看,此时 main() 函数再次捕获了 ValueError,它就是在 bid() 方法中 except 块所捕获的原始异常。

except 和 raise 同时使用

在实际应用中对异常可能需要更复杂的处理方式。当一个异常出现时,单靠某个方法无法完全处理该异常,必须由几个方法协作才可完全处理该异常。也就是说,在异常出现的当前方法中,程序只对异常进行部分处理,还有些处理需要在该方法的调用者中才能完成,所以应该再次引发异常,让该方法的调用者也能捕获到异常。

为了实现这种通过多个方法协作处理同一个异常的情形,可以在 except 块中结合 raise 语句来完成。如下程序示范了except 和 raise 同时使用的方法:class AuctionException(Exception): pass

class AuctionTest:

def __init__(self, init_price):

self.init_price = init_price

def bid(self, bid_price):

d = 0.0

try:

d = float(bid_price)

except Exception as e:

# 此处只是简单地打印异常信息

print("转换出异常:", e)

# 再次引发自定义异常

raise AuctionException("竞拍价必须是数值,不能包含其他字符!")  # ①

raise AuctionException(e)

if self.init_price > d:

raise AuctionException("竞拍价比起拍价低,不允许竞拍!")

initPrice = d

def main():

at = AuctionTest(20.4)

try:

at.bid("df")

except AuctionException as ae:

# 再次捕获到bid()方法中的异常,并对该异常进行处理

print('main函数捕捉的异常:', ae)

main()

上面程序中 9~13 行代码对应的 except 块捕获到异常后,系统打印了该异常的字符串信息,接着引发一个 AuctionException 异常,通知该方法的调用者再次处理该 AuctionException 异常。所以程序中的 main() 函数,也就是 bid() 方法的调用者还可以再次捕获 AuctionException 异常,井将该异常的详细描述信息打印出来。

这种 except 和 raise 结合使用的情况在实际应用中非常常用。实际应用对异常的处理通常分成两个部分:

应用后台需要通过日志来记录异常发生的详细情况;

应用还需要根据异常向应用使用者传达某种提示;

在这种情形下,所有异常都需要两个方法共同完成,也就必须将 except 和 raise 结合使用。

如果程序需要将原始异常的详细信息直接传播出去,Python 也允许用自定义异常对原始异常进行包装,只要将上面 ① 号代码改为如下形式即可:raise AuctionException(e)

上面就是把原始异常 e 包装成了 AuctionException 异常,这种方式也被称为异常包装或异常转译。

自定义异常类

很多时候,程序可选择引发自定义异常,因为异常的类名通常也包含了该异常的有用信息。所以在引发异常时,应该选择合适的异常类,从而可以明确地描述该异常情况。在这种情形下,应用程序常常需要引发自定义异常。

用户自定义异常都应该继承 Exception 基类或 Exception 的子类,在自定义异常类时基本不需要书写更多的代码,只要指定自定义异常类的父类即可。

下面程序创建了一个自定义异常类:class AuctionException(Exception):

pass

上面程序创建了 AuctionException 异常类,该异常类不需要类体定义,因此使用 pass 语句作为占位符即可。

在大部分情况下,创建自定义异常类都可采用与上面程序相似的代码来完成,只需改变 AuctionException 异常的类名即可,让该异常的类名可以准确地描述该异常。

云海天教程网,大量的免费python教程,欢迎在线学习!

python中raise啥意思_python raise什么意思相关推荐

  1. python中raise和raise e区别_python raise和assert的区别

    python中raise和assert的区别 一.使用raise抛出异常 python可以自动触发异常,raise(内置函数)的定义为显示的抛出异常,用户可以使用raise进行判断,显式的引发异常,r ...

  2. python中赋值语句的作用_python中return可以使用赋值语句吗?

    在python中,有各种不同类型的语句.一个python程序是由模块构成的;一个模块由一条或多条语句组成;每个语句由不同的表达式组成;表达式可以创建和操作对象.下面来看看python中的语句. 赋值语 ...

  3. python中case的用法_python中Switch/Case实现的示例代码

    python 的 python中Switch/Case实现的示例代码 学习Python过程中,发现没有switch-case,过去写C习惯用Switch/Case语句,官方文档说通过if-elif实现 ...

  4. python中mean的用法_Python statistics mean()用法及代码示例

    先决条件:统计函数简介 在数据分析和统计方面,Python是一种非常流行的语言.幸运的是,Python3提供了statistics模块,它具有非常有用的功能,例如mean(),median(),mod ...

  5. python中的封装调用_Python基础之封装

    一.什么是封装 在程序设计中,封装(Encapsulation)是对具体对象的一种抽象,即将某些部分隐藏起来,在程序外部看不到,其 含义是其他程序无法调用. 要了解封装,离不开"私有化&qu ...

  6. python中冒号报错_python中一些常见的错误_后端开发

    PHP8 新特性之 Attributes_后端开发 PHP8的Alpha版本,过几天就要发布了,其中包含了不少的新特性,今天呢,我想谈谈Attributes,为啥呢, 是昨天我看到很多群在转发一个文章 ...

  7. python中valueerror是什_Python:ValueError和Exception的区别?

    我试图理解引发ValueError和异常之间的区别.我在同一个代码中尝试了两种方法(甚至在同一个分支中),结果都是一样的--我收到了一条错误消息. 我就这个问题做了一个研究,但是没有发现有人讨论这个问 ...

  8. python中对象的特性_Python深入学习之对象的属性

    Python一切皆对象(object),每个对象都可能有多个属性(attribute).Python的属性有一套统一的管理方案. 属性的__dict__系统 对象的属性可能来自于其类定义,叫做类属性( ...

  9. [转载] python中pass的使用_Python pass详细介绍及实例代码

    参考链接: Python pass语句 Python pass详细介绍及实例代码 Python pass的用法: 空语句 do nothing 保证格式完整 保证语义完整 以if语句为例,在c或c++ ...

最新文章

  1. 美团全链路压测自动化实践
  2. 阿里云域名备案时产品类型
  3. 爆破专栏丨Spring Security系列教程之Spring Security的四种权限控制方式
  4. 进腾讯实习要交钱?腾讯2021年开除70名员工,拉黑13家公司
  5. 避免踩坑:易盾安全老司机起底Android九大漏洞,附解决建议
  6. 学习vim: vim cheat sheet
  7. ORACLE数据库新增表空间的数据存储文件
  8. opencv前景检测
  9. 国产linux聊天软件,程序员的全平台聊天软件:Rocket.Chat
  10. 给定两个水壶,一个可以装4升水,一个能装3升水,水壶上没有任何度量标记。有一水龙头可以用来往壶中灌水。问题是怎样在能装4升的水壶里面恰好只装2升水
  11. stm32核心板可以点亮灯吗_不忘初心牢记使命——自动化科协自行设计开发stm32仿真器...
  12. 联想Thinkpad E470 笔记本 无声音解决方案
  13. 自学前端开发,现在手握大厂offer,我的故事还在继续
  14. 小程序的生命周期和页面的生命周期
  15. 基础的拉普拉斯金字塔融合用于改善图像增强中易出现的过增强问题(一)
  16. STW(stop the )
  17. 如何去掉友情链接的li标签的三种方法
  18. 2d3d卫星地图转换+搜索js+html+css实现
  19. k型热电偶检测温度c语言程序,[请教]普中51单片机与max6675芯片用k型热电偶检测温度的问题...
  20. vue set设置html根字体,vue-quill-editor安装及使用:自定义工具栏和自定义中文字体,把字体写在html的style中...

热门文章

  1. 我的cocos2d-x学习之路
  2. WIN10自带的录屏软件Xbox Game Bar的启动相关问题
  3. 深圳地区近期面试100多道题汇总(含超详细答案)
  4. 中国集成电路产业投资建议与十四五需求规模分析报告2022版
  5. Java实现递归 斐波那契数列 阶乘
  6. 常见的端口号以及协议
  7. Oracle 字符集 原理及问题解决 (全)
  8. 如何分析夹杂在金属液中的微小气泡
  9. 珠宝达人必须知晓的10大宝石产地
  10. 利用计算机解决实际问题,计算机程序可以解决哪些实际问题