异常
异常是什么
- python 使用异常对象来表示异常状态, 并在遇到错误时引发异常
- 每个异常都是某个类
一些常用的内置的异常类
类名 描述
Exception 几乎所有的异常类都是从它派生而来
AttributeError 引用属性或给它复制失败时引发
OSError 操作系统不能执行指定的任务(如打开文件)时引发
IndexError 使用序列中不存在的索引时引发, 为LookupError的子类
KeyError 使用映射中不存在的键时引发,为LookupError的子类
NameError 找不到名称(变量)时引发
SyntaxError 代码不正确时引发
TypeError 将内置操作或函数用于不正确的对象时引发
ValueError 将内置操作或函数用于这样的对象时引发: 其类型正确但包含的值不合适
ZeroDivisionError 在除法或求模运算的第二个参数为零时引发
raise语句,引发异常
-
使用raise,并将一个类(Exception的子类)或实例作为参数
实例一:>>> raise Exception Traceback (most recent call last): File "<stdin>", line 1, in <module> Exception
实例二:
>>> raise Exception('hyperdrive overload') Traceback (most recent call last): File "<stdin>", line 1, in <module> Exception: hyperdrive overload
实例二引发了异常Exception并传递了一个字符串参数, 作为异常引发的提示信息
自定义的异常类
直接或间接地继承Exception(这也意味着从任何内置异常类派生都可以)
实例:
class SomeCustomException(Exception): pass
捕获异常
-
实例一:
x = int(input('Enter the first number: ')) y = int(input('Enter the second number: ')) print(x/y)
当用户输入的第二个参数是0:
Enter the first number: 10 Enter the second number: 0 Traceback (most recent call last): File "C:/Users/dell/Desktop/thePython/reptile/python_github/python/test.py", line 4, in <module> print(x/y) ZeroDivisionError: division by zero
-
捕获异常实例,try/except 语句可以捕获异常
try: x = int(input('Enter the first number: ')) y = int(input('Enter the second number: ')) print(x/y) except ZeroDivisionError: print("sorry ! The second number can't be zero!")
捕捉ZeroDivisionError的异常
- 异常从函数向外传播到调用函数的地方。如果在这里没有被捕获,异常将向程序的最顶层进行传播
不提供参数
- 捕获异常之后如果重新引发他(继续向上传播),可调用raise且不提供任何参数(关闭“抑制”功能)
多个except子句
-
实例:
try: x = int(input('Enter the first number: ')) y = int(input('Enter the second number: ')) print(x/y) except ZeroDivisionError: print("sorry ! The second number can't be zero!") except TypeError: print("That wasn't a number!")
- 多个except可以捕获多种不同的异常
一箭双雕
-
使用一个except子句捕获多种异常,在一个元组中指定这些异常
try: x = int(input('Enter the first number: ')) y = int(input('Enter the second number: ')) print(x/y) except (ZeroDivisionError, TypeError, NameError): print("sorry ! your numbers were bogus...")
一定要注意在except中的异常是在元组中的
捕获对象
-
在except字句中访问异常对象本身
try: x = int(input('Enter the first number: ')) y = int(input('Enter the second number: ')) print(x/y) except (ZeroDivisionError, TypeError, NameError) as e: print(e)
捕获所有异常
-
即使程序处理了好几种异常,但还是会有漏网之鱼,你只需要在except之后不指定任何异常类即可
try: x = int(input('Enter the first number: ')) y = int(input('Enter the second number: ')) print(x/y) except : print("Something wrong")
没有异常时
-
一些情况中,在没有异常时执行一个代码块
while True: try: x = int(input('Enter the first number: ')) y = int(input('Enter the second number: ')) print(x/y) except : print("Something wrong") else: print("I'm so happy ,noting happened") break
仅当没有出现异常时才可以跳出循环
finally
- finally子句,用于发生在异常时执行清理工作,与try配套
- 非常适用于确保文件或网络套接字得以关闭
函数和异常
-
如果不处理异常中的函数,它将向上传播到调用函数的地方。如果在那也未得到处理,异常将继续传播,
直至到达主程序(全局作用域)。如果主程序也未得到异常处理程序,程序将终止并显示栈跟踪消息def faulty(): raise Exception('Something is wrong') def ignore_exception(): faulty() def handle_exception(): try: faulty() except: print("Exception handled")
运行调用:
ignore_exception()
异常栈跟踪消息:
Traceback (most recent call last): File "C:/Users/dell/Desktop/thePython/reptile/python_github/python/test.py", line 15, in <module> ignore_exception() File "C:/Users/dell/Desktop/thePython/reptile/python_github/python/test.py", line 6, in ignore_exception faulty() File "C:/Users/dell/Desktop/thePython/reptile/python_github/python/test.py", line 2, in faulty raise Exception('Something is wrong') Exception: Something is wrong
运行调用:
handle_exception()
异常栈跟踪消息:
Exception handled Process finished with exit code 0