11、异常处理及程序调试
C++或者是Java的编译器就可以捕获很多错误,但python语言只有程序运行后,才能捕获语法错误,因此,需要掌握一定的异常处理语句和程序调试方法。
11.1 异常概述
有些异常是由于敲错导致的,这类错误多数产生的是:SyntaxError: invalidsyntax
(无效的语法)。下表是python种常见的异常:
上面的表格,只做简单了解即可。
11.2 异常处理语句
下面代码出现了错误:
def division():
print('============分苹果===========\n')
apple = int(input('请输入苹果的个数:'))
children = int(input('请输入小朋友的个数:'))
reslut = apple // children
remain = apple - reslut * children
if remain > 0:
print(apple, "个苹果,平均分给", children,
'个小朋友,每人分', reslut, '个,剩下', remain, '个')
else:
print(apple, "个苹果,平均分给", children,
'个小朋友,每人分', reslut)
if __name__ == '__main__':
division()
'''
============分苹果===========
请输入苹果的个数:13
请输入小朋友的个数:4
13 个苹果,平均分给 4 个小朋友,每人分 3 个,剩下 1 个
'''
'''
============分苹果===========
请输入苹果的个数:15
请输入小朋友的个数:0
Traceback (most recent call last):
File "C:/Users/包文强/Desktop/python练习/异常处理/division_apple.py", line 15, in <module>
division()
File "C:/Users/包文强/Desktop/python练习/异常处理/division_apple.py", line 5, in division
reslut = apple // children
ZeroDivisionError: integer division or modulo by zero
'''
上述代码中,假设有0个小朋友,代码出错。
11.2.1 try…except语句
重新修改上面的代码:
def division():
print('============分苹果===========\n')
apple = int(input('请输入苹果的个数:'))
children = int(input('请输入小朋友的个数:'))
reslut = apple // children
remain = apple - reslut * children
if remain > 0:
print(apple, "个苹果,平均分给", children,
'个小朋友,每人分', reslut, '个,剩下', remain, '个')
else:
print(apple, "个苹果,平均分给", children,
'个小朋友,每人分', reslut)
if __name__ == '__main__':
try:
division()
except ZeroDivisionError:
print("\n出错了,~_~——苹果不能给0个小朋友分!")
'''
============分苹果===========
请输入苹果的个数:12
请输入小朋友的个数:0
出错了,~_~——苹果不能给0个小朋友分!
'''
上述代码,如果输入的苹果数或者是小朋友数目为小数,依然会报错:
'''
============分苹果===========
请输入苹果的个数:13
请输入小朋友的个数:2.5
Traceback (most recent call last):
File "C:/Users/包文强/Desktop/python练习/异常处理/division_apple.py", line 16, in <module>
division()
File "C:/Users/包文强/Desktop/python练习/异常处理/division_apple.py", line 4, in division
children = int(input('请输入小朋友的个数:'))
ValueError: invalid literal for int() with base 10: '2.5'
'''
解决办法:为try…except
语句再添加一个except
语句,用于处理抛出ValueError
异常的情况:
def division():
print('============分苹果===========\n')
apple = int(input('请输入苹果的个数:'))
children = int(input('请输入小朋友的个数:'))
reslut = apple // children
remain = apple - reslut * children
if remain > 0:
print(apple, "个苹果,平均分给", children,
'个小朋友,每人分', reslut, '个,剩下', remain, '个')
else:
print(apple, "个苹果,平均分给", children,
'个小朋友,每人分', reslut)
if __name__ == '__main__':
try:
division()
except ZeroDivisionError:
print("\n出错了,~_~——苹果不能给0个小朋友分!")
except ValueError as e: #用别名 e 来代替
print('输入错误,应该为正数:', e)
'''
============分苹果===========
请输入苹果的个数:12
请输入小朋友的个数:2.6
输入错误,应该为正数: invalid literal for int() with base 10: '2.6'
'''
也可以将多个异常处理放在一起:
except (ValueError, ZeroDivisionError) as e:
print('输入错误:', e)
'''
============分苹果===========
请输入苹果的个数:14
请输入小朋友的个数:0
输入错误: integer division or modulo by zero
'''
'''
============分苹果===========
请输入苹果的个数:12
请输入小朋友的个数:8.6
输入错误: invalid literal for int() with base 10: '8.6'
'''
11.2.2 try…except…else语句
try
后面加上else
后表示若没有发生异常所执行的语句:
def division():
print('============分苹果===========\n')
apple = int(input('请输入苹果的个数:'))
children = int(input('请输入小朋友的个数:'))
reslut = apple // children
remain = apple - reslut * children
if remain > 0:
print(apple, "个苹果,平均分给", children,
'个小朋友,每人分', reslut, '个,剩下', remain, '个')
else:
print(apple, "个苹果,平均分给", children,
'个小朋友,每人分', reslut)
if __name__ == '__main__':
try:
division()
except ZeroDivisionError:
print("\n出错了,~_~——苹果不能给0个小朋友分!")
except ValueError as e:
print('输入错误:', e)
else:
print("分苹果任务顺利完成!")
'''
============分苹果===========
请输入苹果的个数:17
请输入小朋友的个数:3
17 个苹果,平均分给 3 个小朋友,每人分 5 个,剩下 2 个
分苹果任务顺利完成!
'''
11.2.3 try…except…finally语句
完整的异常处理语句应该包含finally
代码块,一般情况,无论程序异常与否,finally
代码块中的代码都会被执行。
def division():
print('============分苹果===========\n')
apple = int(input('请输入苹果的个数:'))
children = int(input('请输入小朋友的个数:'))
reslut = apple // children
remain = apple - reslut * children
if remain > 0:
print(apple, "个苹果,平均分给", children,
'个小朋友,每人分', reslut, '个,剩下', remain, '个')
else:
print(apple, "个苹果,平均分给", children,
'个小朋友,每人分', reslut)
if __name__ == '__main__':
try:
division()
except ZeroDivisionError:
print("\n出错了,~_~——苹果不能给0个小朋友分!")
except ValueError as e:
print('输入错误:', e)
else:
print("分苹果任务顺利完成!")
finally:
print('无论是否合理分配,我们都进行了一次分苹果操作!')
'''
============分苹果===========
请输入苹果的个数:13
请输入小朋友的个数:4.8
输入错误: invalid literal for int() with base 10: '4.8'
无论是否合理分配,我们都进行了一次分苹果操作!
'''
下图是异常处理机制的执行关系:
11.2.4 使用raise语句抛出异常
如果某个函数或方法可能会产生异常,但不想在当前函数或方法中处理这个异常,则可以使用raise
语句在函数或方法中抛出异常。
def division():
print('============分苹果===========\n')
apple = int(input('请输入苹果的个数:'))
children = int(input('请输入小朋友的个数:'))
if apple < children:
raise ValueError('苹果太少,不够分。。。。。')
reslut = apple // children
remain = apple - reslut * children
if remain > 0:
print(apple, "个苹果,平均分给", children,
'个小朋友,每人分', reslut, '个,剩下', remain, '个')
else:
print(apple, "个苹果,平均分给", children,
'个小朋友,每人分', reslut)
if __name__ == '__main__':
try:
division()
except ZeroDivisionError:
print("\n出错了,~_~——苹果不能给0个小朋友分!")
except ValueError as e:
print('输入错误:', e)
else:
print("分苹果任务顺利完成!")
finally:
print('无论是否合理分配,我们都进行了一次分苹果操作!')
'''
============分苹果===========
请输入苹果的个数:12
请输入小朋友的个数:23
输入错误: 苹果太少,不够分。。。。。
无论是否合理分配,我们都进行了一次分苹果操作!
'''
11.3 程序调试
11.3.1 使用自带的IDLE进行程序调试
多数的集成开发工具都提供了程序调试功能。在Python中可以使用IDLE进行调试。
11.3.2 使用assert语句调试程序
通常情况下,assert
语句可以和异常处理语句结合使用。
def division():
print('============分苹果===========\n')
apple = int(input('请输入苹果的个数:'))
children = int(input('请输入小朋友的个数:'))
assert apple > children, '苹果不够分'
reslut = apple // children
remain = apple - reslut * children
if remain > 0:
print(apple, "个苹果,平均分给", children,
'个小朋友,每人分', reslut, '个,剩下', remain, '个')
else:
print(apple, "个苹果,平均分给", children,
'个小朋友,每人分', reslut)
if __name__ == '__main__':
try:
division()
except ZeroDivisionError:
print("\n出错了,~_~——苹果不能给0个小朋友分!")
except ValueError as e:
print('输入错误:', e)
else:
print("分苹果任务顺利完成!")
finally:
print('无论是否合理分配,我们都进行了一次分苹果操作!')
'''
============分苹果===========
请输入苹果的个数:12
请输入小朋友的个数:13
无论是否合理分配,我们都进行了一次分苹果操作!
Traceback (most recent call last):
File "C:/Users/包文强/Desktop/python练习/异常处理/division_apple.py", line 17, in <module>
division()
File "C:/Users/包文强/Desktop/python练习/异常处理/division_apple.py", line 5, in division
assert apple > children, '苹果不够分'
AssertionError: 苹果不够分
'''
assert
语句只在调试阶段有效。我们可以通过在执行python命令时加入-O
(大写)参数来关闭assert
语句。
C:\Users\包文强\Desktop\python练习\异常处理>python -O division_apple.py
============分苹果===========
请输入苹果的个数:13
请输入小朋友的个数:25
13 个苹果,平均分给 25 个小朋友,每人分 0 个,剩下 13 个
分苹果任务顺利完成!
无论是否合理分配,我们都进行了一次分苹果操作!
上述语句执行后,关闭了assert
操作。