目录
程序在运行时,如果python遇到错误,会停止程序的执行,并提示一些错误信息,这就是异常。
程序停止执行,并提示错误信息的动作称为抛出异常。
程序在执行过程中很难将所有的特殊情况都处理到,通过异常捕获可以针对突发事件进行集中处理,从而保证程序的稳定性和健壮性。
python标准错误处理:
- try:
- 可能出错的地方
- except:
- 错误捕获,出错时要执行的代码
- else:
- 没有错误时要执行的代码
- finally:
- 不管有没有错误都要执行的代码
示例,输入数字,如果输入的不是数字,则捕获异常并处理。
- try:
- num = int(input('请输入数字:'))
- except:
- print('请输入正确的数字')
- else:
- print('num=',num)
- finally:
- print('程序测试结束')
显示结果,如果输入非数字,会提示 ''请输入正确的数字;
- 请输入数字:fd
- 请输入正确的数字
- 程序测试结束
-
- 请输入数字:12
- num= 12
- 程序测试结束
简单的异常捕获可以只有 try...except...。
python定义的常见异常类型如下:
异常类型 | 说明 |
AttributeError | 属性错误,特性引用和赋值失败时会引发属性错误 |
NameError | 试图访问的变量名不存在 |
SyntaxError | 语法错误,代码形式错误 |
Exception | 所有异常的基类,因为所有python异常类都是基类Exception的其中一员,异常都是从基类Exception继承的,并且都在exception python模块中定义 |
IOError | python ioerror,输入输出错误,一般常见于打开不存在的文件时引发IOError错误 |
KeyError | 使用了映射中不存在的关键字(键)时引发的关键字错误 |
IndexError | 索引错误,使用的索引不存在,或索引超出序列范围 |
TypeError | 类型错误,某些函数或者方法只适用于特定数据类型,若数据类型操作不当会抛出此错误 |
ZeroDivisionError | 除数为0时抛出此异常 |
ValueError | 值错误,传给对象的参数类型不正确,例如,int()函数中传入了非数字的字符串类型 |
通常不需要我们记住这些异常类型,在捕获异常时使用 BaseException 来捕捉错误,打印出具体的错误类型。
- try:
- 可能出错的地方
- except BaseException as e:
- print(e)
- else:
- 没有错误时要执行的代码
- finally:
- 不管有没有错误都要执行的代码
对如上代码进行改造:
- from ast import Try
- from tkinter import E
-
-
- try:
- num = int(input('请输入数字:'))
- except BaseException as e:
- print(e)
- else:
- print('num=',num)
- finally:
- print('程序测试结束')
显示结果:
请输入数字:s
invalid literal for int() with base 10: 's'
程序测试结束
另外,还可以使用 traceback 库打印哪一行有错误,错误是什么,如下示例:
- import traceback
-
- try:
- num = int(input('请输入数字:'))
- except BaseException as e:
- # traceback.print_exc() 打印出错误类型和错误位置
- print(traceback.print_exc())
- else:
- print('num=',num)
- finally:
- print('程序测试结束')
显示结果,会提示哪一行有错误,并且错误类型也会打印出来。
请输入数字:s
Traceback (most recent call last):
File "e:/1_tempFile/1_learn_code/VSCode/python_test/python_exception/try_except.py", line 4, in
num = int(input('请输入数字:'))
ValueError: invalid literal for int() with base 10: 's'
None
程序测试结束
当函数/方法执行出现异常,会将异常传递给函数调用的一方;如果传递到主程序,仍然没有异常处理,程序会被终止。
所以我们可以在主函数中增加异常捕获,在主函数调用的其它函数出现异常,会传递到主函数的异常捕获中。
示例:在函数func1()中提示用户输入一个整数并返回,func2()调用func1(),主程序调用func2()。
- import traceback
-
-
- def func1():
- return int(input('请输入一个整数:'))
-
-
- def func2():
- func1()
-
-
- if __name__ == '__main__':
- try:
- func2()
- except BaseException as e:
- # traceback.print_exc() 打印出错误类型和错误位置
- print(traceback.print_exc())
- else:
- pass
- finally:
- print('程序测试结束')
显示结果:
请输入一个整数:s
Traceback (most recent call last):
File "e:/1_tempFile/1_learn_code/VSCode/python_test/python_exception/try_except.py", line 13, in
func2()
File "e:/1_tempFile/1_learn_code/VSCode/python_test/python_exception/try_except.py", line 8, in func2
func1()
File "e:/1_tempFile/1_learn_code/VSCode/python_test/python_exception/try_except.py", line 4, in func1
return int(input('请输入一个整数:'))
ValueError: invalid literal for int() with base 10: 's'
None
程序测试结束
除了代码执行错误导致异常外,还可以根据特定需求抛出异常。
抛出异常的步骤:
示例,定义input_password()函数,提示用户输入密码;如果用户输入长度<8,抛出异常;如果用户输入长度>=8,返回输入的密码。
- import traceback
-
- def input_password():
- pwd = input("请输入密码:")
-
- if len(pwd) >= 8:
- return pwd
-
- e = Exception("密码长度不足8位")
-
- raise e
-
-
- if __name__ == '__main__':
- try:
- user_pwd = input_password()
- print(user_pwd)
- except Exception as e:
- print(e)
- except:
- print(traceback.print_exc())
显示结果:
全文参考: