初始Python篇(8)—— 异常

找往期文章包括但不限于本期文章中不懂的知识点:

个人主页: 我要学编程(ಥ_ಥ)-CSDN博客

所属专栏: Python

目录

异常介绍

异常的处理

try-except

try-except-else

try-except-else-finally

异常的抛出

常见的异常类型


异常介绍

在学习异常之前,先了解bug的概念。简单理解就是程序运行不起来或者运行起来之后,输出的结果不符合我们的预期。有了bug肯定是要去解决的。而解决bug就离不开异常的处理。

如果是程序运行出错,有两种情况:1、程序本身就存在问题;2、对于存在输入型程序来说,可能是用户的输入导致程序报错。

第一种情况,就需要我们自己去排查,看是哪里出现了语法错误。

第二种情况,就需要用到我们今天学习的异常处理。

如果是程序运行之后,结果不符合我们的预期,这就需要用到调试工具了。

异常的处理

try-except

Python中对于异常的处理是通过 try-except 语句来捕获异常的。

语法:

python 复制代码
try:
    ... // 可能出现异常的代码
except 异常类型A:
    ... // 处理异常的代码(程序报错之后执行的代码)
except 异常类型B:
    ... // 处理异常的代码(程序报错之后执行的代码)

代码演示:

python 复制代码
try:
    num1 = int(input('请输入一个数:'))
    num2 = int(input('请输入一个数:'))
    print('{0} / {1}的结果是:{2}'.format(num1, num2, num1//num2)) # // 这是整数除法
except ZeroDivisionError:
    print('除数为0异常')

上面只是一种情况,还会出现其他的异常输入。

从上面的结果,我们可以看出:程序抛出异常之后,就不会继续执行下去了,要么去执行捕获异常之后的代码,要么直接就摆烂了。

处理异常:

python 复制代码
except ValueError:
    print('请输入一个合法的整数')

因此,当我们以后遇到异常之后,即使不知道是啥异常,但只要我们将异常给捕获了,程序就不会直接结束,而是会执行 except 语句代码。

try-except-else

除此之外,Python还提供了类似 while-else的语句。当程序将try中的代码全部执行完毕之后(意味着不存在异常),就会去执行 else 语句。

语法:

python 复制代码
try:
    ... // 可能出现异常的代码
except 异常类型A:
    ... // 处理异常的代码(程序报错之后执行的代码)
except 异常类型B:
    ... // 处理异常的代码(程序报错之后执行的代码)

....... // 剩余异常

else:
    ... // 程序没有异常将会执行的代码

代码演示:

python 复制代码
try:
    num1 = int(input('请输入一个数:'))
    num2 = int(input('请输入一个数:'))
    print('{0} / {1}的结果是:{2}'.format(num1, num2, num1//num2)) # // 这是整数除法
except ZeroDivisionError:
    print('除数为0异常')
except ValueError:
    print('请输入一个合法的整数')
else:
    print('程序执行完毕')

运行结果:

else 语句中的代码主要是 用来区分 程序无异常时,将会执行的代码。因此我们可以将计算的结果放到else语句中去输出。

代码演示:

python 复制代码
try:
    num1 = int(input('请输入一个数:'))
    num2 = int(input('请输入一个数:'))
    result = num1 // num2
except ZeroDivisionError:
    print('除数为0异常')
except ValueError:
    print('请输入一个合法的整数')
else:
    print('{0} / {1}的结果是:{2}'.format(num1, num2, result))
    print('程序执行完毕')

这可以增加代码整体布局的美观性。

try-except-else-finally

当程序抛出异常之后,try语句中剩余的代码并不会执行了,那如果剩余的代码中,有一些逻辑是为了安全性考虑的呢,这如果不执行的话,那就会导致程序存在安全问题。如果要执行的话,该怎么办呢?将一些重要逻辑代码全部放到except中,每一个语句都放一份,这样的确可行,但是太过冗余了。因此,便有了 finally 语句:无论程序是否抛出异常,其中的代码都会执行。

语法:

python 复制代码
try:
    ... // 可能出现异常的代码
except 异常类型A:
    ... // 处理异常的代码(程序报错之后执行的代码)
except 异常类型B:
    ... // 处理异常的代码(程序报错之后执行的代码)

....... // 剩余异常

else:
    ... // 程序没有异常将会执行的代码
finally:
    ... // 无论程序是否抛出异常都会被执行

代码演示:

python 复制代码
try:
    num1 = int(input('请输入一个数:'))
    num2 = int(input('请输入一个数:'))
    result = num1 // num2
except ZeroDivisionError:
    print('除数为0异常')
except ValueError:
    print('请输入一个合法的整数')
else:
    print('{0} / {1}的结果是:{2}'.format(num1, num2, result))
    print('程序执行完毕')
finally:
    print('I love coding')

运行结果:

修改后的结果:

异常的抛出

一个程序需要用户某些值时,但是用户输入的值又不符合我们的要求,针对这种情况就可以去让程序手动抛出异常。 这个异常是通过 raise 关键字来抛出的。

语法:

python 复制代码
raise [Exception类型(异常描述信息)]

代码演示:

python 复制代码
try:
    num = int(input('请输入一个1-100之间的整数:'))
    if num >= 1 and num <= 100:
        print(f'你输入的数字是:{num}')
    else:
        raise Exception('不符合程序要求')
except ValueError:
    print('请输入一个整数')
# e这里是作为异常对象,如果我们去打印Exception时打不出其中的异常信息
# 需要用到 as 别名 的语法,然后去打印e这个对象,就可以将异常信息大于出来
except Exception as e:
    print(e)

运行结果:

因为 ValueError 这是Python内置的异常类,当其中的异常信息已经被填充了,所以这就无需我们手动填充,并且也不需要我们去起别名。

注意:

1、在使用 raise 关键字抛异常时,这个异常可以是内置的异常,也可以是我们自己构造出来的异常。但我们在使用自己构造的异常时,最好还是去描述异常的详细信息,以便于后续排查。

2、在except 语句中,去捕获异常时,是从上到下依次判断的,也就是先是判断异常是否为 ValueError,再去判断是否为 Exception。由于 ValueError 是 Exception 的子类,如果当 Exception 写在前面先判断时,就会出现无论是什么样的异常都会被Exception给捕获,从而导致异常被错误的处理了。这里的"子类"、"父类"等概念先不用管,后面学习类和对象就明白了。

3、我们如果先想要打印出描述异常的详细信息,就需要给异常起一个别名,然后通过别名去打印出来。

常见的异常类型

|-------------------|----------------------|
| 异常类型 | 描述类型 |
| ZeroDivisionError | 当除数为0时,所引发的异常 |
| IndexError | 索引超出范围所引发的异常 |
| KeyError | 字典取值时,key不存在所引发的异常 |
| NameError | 使用未声明的变量时,所引发的异常 |
| SyntaxError | 语法错误(一般,编译器能识别出来) |
| ValueError | 传入的值错误 |
| AttributeError | 访问对象的属性或者方法不存在所引发的异常 |
| TypeError | 类型不合适所引发的异常 |
| IndentationError | 不正确的缩进所引发的异常 |

下面我们对上述涉及的异常来演示一下:

python 复制代码
# ZeroDivisionError
# print(10 / 0)

# IndexError
# lst = [1,2]
# print(lst[3])

# KeyError
# 只有以下两种方式触发:KeyError
# d = {'张三':18, '李四':20}
# d.pop('小军')
# print(d['小明'])

# NameError
# print(name, age)

# SyntaxError
# 学过C语言的同学,刚接触可能会犯这样的错误
# for (int i = 0; i < 10; i++) {
#     printf("%d", i);
# }

# ValueError
# age = int('18.5')

# TypeError
# print('12'+12)

# IndentationError
# if 1 == 1:
# print(1)

由于我们还没有学习 类和对象,因此这里的 AttributeError 不是很好演示。等后面我们学习了类和对象之后,再去尝试就行了。

好啦!本期 初始Python篇(8)------ 异常 的学习之旅 就到此结束啦!我们下一期再一起学习吧!

相关推荐
CyberScriptor几秒前
PHP语言的字符串处理
开发语言·后端·golang
wfsm6 分钟前
uniapp中h5使用地图
开发语言·javascript·uni-app
还是车万大佬12 分钟前
C语言与ASCII码应用之简单加密
c语言·开发语言·算法
Eiceblue23 分钟前
Python 在PDF中添加数字签名
开发语言·vscode·python·pycharm·pdf
DevOpsDojo23 分钟前
Perl语言的数据结构
开发语言·后端·golang
q567315231 小时前
利用Python实现Union-Find算法
android·python·算法
晒足以百八十1 小时前
数据挖掘实训:基于CEEMDAN与多种机器学习模型股票预测与时间序列建模
python·机器学习·数据挖掘
浪前1 小时前
【算法】移除元素
开发语言·数据结构·算法
2401_898410691 小时前
T-SQL语言的软件工程
开发语言·后端·golang