脚本之家,脚本语言编程技术及教程分享平台!
分类导航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服务器之家 - 脚本之家 - Python - Python学习之自定义异常详解

Python学习之自定义异常详解

2022-11-03 10:45渴望力量的哈士奇 Python

这篇文章主要为大家介绍了Python中如何自定义异常,以及自定义抛出异常的关键字—raise的用法,文中示例代码讲解详细,感兴趣的小伙伴可以了解一下

在上一章我们学习了 异常的三个关键字,分别是try、except 以及 finally。我们知道在 try 代码块中如果遇到错误就会抛出异常,交给 except 提前定义好的错误类型进行匹配并捕获,如果成功捕获到异常就会交给 except 的代码块进行执行,最后的 finally 是无论如何都会执行的代码块。

那么在 try 语法块中是谁抛出的异常?优势如何抛出的呢?首先抛出异常的是 Python 的解释器,它在脚本执行的时候发现了错误并将其抛出,而如何抛出的呢?捕获的异常优势如何定义的呢?

带着这样的疑问,我们就学习一下如何自己书写一个异常类型,并主动抛出异常。

当我们学会了自定义一个异常以及主动抛出异常的时候,就可以主宰一个异常的发生。在之前我们学习的如 NameError 、TypeError … 这些都是 Python 内置给我们定义好的,我们只能老老实实的使用他们。通过今天的学习,我们就可以变被动为主动,因为在实际工作中有太多的场景是 内置的异常所触及不到的,而这时候使用我们自己定义的异常类型就可以更好的打通业务。

自定义抛出异常关键字 - raise

raise 关键字的功能:可以将信息已报错的形式抛出

raise 关键字的用法:示例如下

?
1
2
3
4
5
6
7
8
9
# 用法:
raise 异常类型(message)
 
# 参数:
# message:为要输出的错误信息
# 这样的当程序执行到 raise 关键字这一行的时候,python 解释器就会根据 raise 的要求抛出异常错误。
 
# 返回值:
# 因为 raise 关键字是抛出一个异常,所以是没有返回值的

演示小案例 - 1

?
1
2
3
4
5
6
7
8
9
10
raise ValueError('使用 raise 主动抛出异常。')
 
# >>> 执行结果如下:
# >>> Traceback (most recent call last):
# >>>   File "D:\PycharmProjects\XXXXX\XXXXX\XXXXX.py", line 87, in <module>
# >>>     raise ValueError('使用 raise 主动抛出异常。')
# >>> ValueError: 使用 raise 主动抛出异常。
 
# >>> 这里我们使用的是 ValueError 异常类型,其实我们可以使用任意的异常类型。
# >>> 实在不知道使用什么异常类型,使用 Exception 也是一个不错的选择

演示小案例 - 2

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def test(num):
    if num == 100:
        raise ValueError('传入的参数 \'num\' 不可以为100')
    return num
 
 
result = test(100)
print(result)
 
# >>> 执行结果如下:
# >>> Traceback (most recent call last):
# >>>   File "D:\PycharmProjects\XXXXX\XXXXX\XXXXX.py", line 21, in <module>
# >>>     result = test(100)
# >>>   File "D:\PycharmProjects\XXXXX\XXXXX\XXXXX.py", line 17, in test
# >>>     raise ValueError('传入的参数 \'num\' 不可以为100')
# >>> ValueError: 传入的参数 'num' 不可以为100

那么主动抛出的 raise 能不能被捕获呢?我们试一下。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
def test(num):
    if num == 100:
        raise ValueError('传入的参数 \'num\' 不可以为100')
    return num
 
 
# result = test(100)
 
 
def test2(num):
    try:
        return test(num)
    except ValueError as e:
        return e
 
 
result = test2(100)
print(result)
 
# >>> 执行结果如下:
# >>> 传入的参数 'num' 不可以为100

再思考一个问题,如果 raise 关键字后面不跟随错误类型,仅仅是 字符串提示信息,能否进行抛出错误呢?

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
def test3():
    raise '主动抛出异常'
 
 
test3()
 
# >>> 执行结果如下:
# >>> Traceback (most recent call last):
# >>>   File "D:\PycharmProjects\XXXXX\XXXXX\XXXXX.py", line 38, in <module>
# >>>     test3()
# >>>   File "D:\PycharmProjects\XXXXX\XXXXX\XXXXX.py", line 36, in test3
# >>>    raise '主动抛出异常'
# >>> TypeError: exceptions must derive from BaseException
# >>> TypeError: 异常必须得基于基础异常类 (BaseException:基础异常类 - 也就是 'Exception')
 
 
# >>> 这里的确抛出了一个异常,但是并不是我们 raise 关键字主动抛出的异常
# >>> 而是 Python解释器发现 raise 关键字的用法不正确抛出的 TypeError 的 异常类型

由此得出结论: raise 关键字 后面必须要配合一个 异常类型 ,才可以正常使用。

自定义异常类

Exception 是一个通用异常类型,在我们不知道、不确定该使用什么异常类型的时候,就可以通过 Exception 来捕获 或者 结合 raise 关键字主动抛出异常。

同时 Exception 是所有异常类型的基类(父类),所以如果我们想要自定义一个异常类型,就需要继承 Exception 基类 。

基类继承之后我们还需要 自定义一个错误的消息;满足这两个条件之后,我们就可以去自定义一个异常类。

总结:

  • 自定义异常必须继承基类:Exception
  • 需要在构造函数中自定义错误的信息

来看一个示例:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class NewError(Exception):
    def __init__(self, message):
        self.message = message
 
 
def test():
    raise NewError('这是一个自定义异常')
 
 
try:
    test()
except NewError as e:
    print(e)
    
# >>> 执行结果如下:
# >>> 这是一个自定义异常

接下来 我们自定义一个检查 name 传参的异常,然后进行校验

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
class CheckNameError(Exception):
 
    def __init__(self, message):
        self.message = message
 
 
def check_name(name):
    if name == 'Neo':
        raise CheckNameError('\'Neo\'的名字不可以作为传参参数')
    return name
 
try:
    check_name('Neo')
except CheckNameError as e:
    print(e)
    
# >>> 执行结果如下:
# >>> Neo'的名字不可以作为传参参数    
 
 
# 尝试一下如果不使用我们 try 捕获我们的自定义异常试试
 
 
class CheckNameError(Exception):
 
    def __init__(self, message):
        self.message = message
 
 
def check_name(name):
    if name == 'Neo':
        raise CheckNameError('\'Neo\'的名字不可以作为传参参数')
    return name
 
check_name('Neo')
 
# >>> 执行结果如下:
# >>> __main__.CheckNameError: 'Neo'的名字不可以作为传参参数

总结

该章节我们主要学习如何自定义抛出一个异常,以及如何自动定义一个异常类型。

在工作中,定义一个符合业务场景的异常类型,可以更适合我们的开发与错误显示。

到此这篇关于Python学习之自定义异常详解的文章就介绍到这了,更多相关Python自定义异常内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/weixin_42250835/article/details/123512888

延伸 · 阅读

精彩推荐
  • Pythontensorflow 使用flags定义命令行参数的方法

    tensorflow 使用flags定义命令行参数的方法

    本篇文章主要介绍了tensorflow 使用flags定义命令行参数的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    一个人的场域6572021-02-04
  • Pythonmatplotlib自定义鼠标光标坐标格式的实现

    matplotlib自定义鼠标光标坐标格式的实现

    这篇文章主要介绍了matplotlib自定义鼠标光标坐标格式的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的...

    mighty133862021-08-23
  • Python聊聊python的gin库的介绍和使用

    聊聊python的gin库的介绍和使用

    gin像一个封装了参数配置的类,使用这个类将使得大量的参数配置变得简单清晰,本文重点给大家介绍python的gin库的介绍和使用,感兴趣的朋友跟随小编一...

    街灯下的哥斯拉4362021-10-16
  • PythonPython3.5集合及其常见运算实例详解

    Python3.5集合及其常见运算实例详解

    这篇文章主要介绍了Python3.5集合及其常见运算,结合实例形式分析了Python3.5集合的定义、功能、交集、并集、差集等常见操作技巧与相关注意事项,需要的朋...

    loveliuzz7372021-06-22
  • Pythonpython构造函数init实例方法解析

    python构造函数init实例方法解析

    这篇文章主要介绍了python构造函数init实例方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参...

    蒸汽泡3672020-04-12
  • Python解决pycharm修改代码后第一次运行不生效的问题

    解决pycharm修改代码后第一次运行不生效的问题

    这篇文章主要介绍了解决pycharm修改代码后第一次运行不生效的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    effortsing11862021-09-03
  • Python使用pytorch完成kaggle猫狗图像识别方式

    使用pytorch完成kaggle猫狗图像识别方式

    今天小编就为大家分享一篇使用pytorch完成kaggle猫狗图像识别方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧 ...

    charsenhz4912020-04-28
  • Python六行python代码的爱心曲线详解

    六行python代码的爱心曲线详解

    这篇文章主要介绍了六行python代码的爱心曲线详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下...

    半吊子全栈工匠7052021-06-27