这节课我们讲要了解一个新的知识:异常处理。假设我们写一个程序,计算两个数相除的商,程序运行后除数输入0。再假设程序中要求用户输入一个整数,用户输入了一个浮点数。这两种情况程序肯定会报错,但是这种问题我们在写程序时有办法控制吗?那如果用户就这样输入了,我们又该怎么处理呢?我们一起来了解这一课的知识。
一、什么是异常在程序执行中,任何中断正常程序流程的条件都是异常。例如,发生下列情况时,会出现异常:
- 类型无法转换
- 除数为0
- 打开的文件不存在
- 需要从网络获取内容,电脑没有联网
- 访问列表等类型时索引越界
- ……
异常和程序代码错误是有区别的。产生异常的代码本身没有问题,在执行程序时由于不可预见的操作而产生的。而错误是代码本身的问题造成程序无法运行,比如以下问题不属于异常,属于错误:代码缩进错误,分支或循环结构语句后面忘记加冒号等等。
在编写程序时,我们可以事先考虑程序运行时可能出现的异常,并对异常进行处理,避免由于异常而导致程序非正常退出。下面我们具体看一下Python中的异常处理语句。
二、try…except…格式try…except……的语法格式:
try:
<语句块1>
except:
<语句块2>
当碰到触发异常的语句,try代码块的剩余代码会被忽略,except代码块的代码将被执行。
我们看一下具体的例子:
try:
a = int(input("请输入被除数:"))
b = int(input("请输入除数:"))
c = a / b
print(c)
except:
print('除数不能为0')
以上代码中,运行时被除数输入整数、除数如果输入非0的整数,程序正常运行,会计算出结果并打印;如果被除数和除数输入非整数或除数输入0,则print(c)不会再运行,而直接执行except中的语句块,打印“除数不能为0”
三、try…except…except…格式try…except…except…的语法格式:
try:
<语句块1>
except:
<语句块2>
except:
<语句块3>
当碰到触发异常的语句时,try代码块的剩余代码将被忽略。根据错误的具体情况,选择except代码块的代码执行。
我们看具体的例子:
try:
a = int(input('请输入被除数:'))
b = int(input('请输入除数:'))
m = a / b
print('商是', m)
except ValueError:
print('输入的不是数字')
except ZeroDivisionError:
print('除数为0')
except:
print('其他错误')
多个except语句需要指定触发异常的Error类型。
常见的Error类型如下:
异常名称 | 描述 |
ValueError | 值错误,输入的数据跟要求不符合 |
ZeroDivisionError | 除0错误,除数为0 |
NameError | 名称错误,变量没有被定义 |
IndexError | 索引错误,索引越界 |
KeyError | 键错误,调用字典不存在的键 |
TypeError | 数据类型错误,如字符串与数字相加 |
FileNotFoundError | 文件不存在错误,读取不存在的文件 |
以上代码运行时,如输入两个整数,程序正常运行,输出商的结果;如果输入的非整数,则运行“except ValueError”中的代码块,打印“输入的不是数字”;如果除数输入0,则运行“except ZeroDivisionError”中的代码块,打印“除数为0”;如果出现其他错误,则运行最后一个except中的语句块,打印“其他错误”。
四、try…except…else…finally…格式try…except…else…finally…的语法格式:
try:
<语句块1>
except:
<语句块2>
else:
<语句块3>
finally:
<语句块4>
当碰到触发异常的语句时,try代码块的剩余代码将会被忽略,执行except语句块;当try语句块正确时,try代码块执行完毕,执行else语句块;不管try代码块正确与否,finally代码块均要执行。
我们看具体的例子:
try:
f = open('students.csv')
students = f.read().strip().split(',')
f.close()
except FileNotFoundError:
print('文件不存在!')
else:
print(students)
finally:
print('程序运行结束!')
程序运行后读取students.csv文件,如果文件读取成功,读取文件内容并赋值给列表students;如果文件不存在,则执行except语句块的内容,打印“文件不存在!”。try语句块成功执行后,执行else语句块中的内容打印列表内容。
最后,无论try语句有无错误,finally代码块一定会被执行,最后打印“程序运行结束!”。
五、课后思考题1、选择题:
运行下列程序段时输入“yes”,则输出的结果是( )
try:
x = eval(input())
print(x)
except NameError:
print('ok')
A. yes B. ok C. 无法运行 D. 3
2、判断题:
异常处理结构中,try程序段中的每一个运行错误语句,都要转移到except程序段中,执行异常处理语句。
3、编程题
有如下列表:
['伍白安', '永映秋', '秋卓然', '叶冬莲', '卓运华', '邸美丽']
输入学号,打印学生的姓名。如果学号不存在,则输出“学号不存在”。程序可重复执行,输入字母“q”退出程序,
六、上节课思考题答案参考代码:
import csv
with open(r'D:\score.csv', 'r') as f:
score = list(csv.reader(f))
candidate = []
for row in score[1:]:
if float(row[1]) >= 85 and float(row[2]) >= 90 and float(row[3]) >= 90:
candidate.append(row[0])
with open(r'D:\candidate.csv', 'w', newline='') as f:
writer = csv.writer(f)
writer.writerow(candidate)