异常是指程序中的例外,违例,影响程序正常执行的情况。
异常机制是指程序出现错误后,程序的处理方法。
异常的工作原理:
try的工作原理是,当开始一个try语句后,python就在当前程序的上下文中作标记, 当异常出现并捕获后继续执行后续的代码,try子句先执行,接下来会发生什么依赖 于执行时是否出现异常。
➢如果当try后的语句执行时发生异常,python就跳出try并执行第一个匹配该异常的 except子句,异常处理完毕,控制流就通过整个try语句(除非在处理异常时又引发 新的异常)。
➢如果在try后的语句里发生了异常,却没有匹配的except子句,异常将被递交到上 层的try,或者到程序的最上层(这样将结束程序,并打印缺省的出错信息)。
➢如果在try子句执行时没有发生异常,python将执行else语句后的语句(如果有else 的话),然后控制流通过整个try语句。
➢不管执行try语句是否发生异常,都将会执行finally语句块的语句(如果有的话)。
#简单的异常
>>> 1/0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero
>>> i/1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'i' is not defined
异常的的定义
try:
<语句>#可能发生异常的代码
except<名字>:
<语句>#如果在try部份引发了'name'异常
except<名字> as <异常参数>:
<语句>#如果引发了‘name’异常,获得附加的异常对象
else:
<语句>#如果没有异常发生
将可能发异常的语句,放到try语句块中,让except语句捕获异 常信息并处理:
#coding=utf-8
try :
fp = open("c:\\file.txt",'r')
fp.write("test")
fp.close()
except IOError :
print ("文件写入失败!")
else :
print ("文件写入成功!")
#捕获多个异常
try:
print("1")
shutil.copy("e:\\sdsddfsdfsfds","e:\\")
print("2")
except (FileNotFoundError,TypeError) as e: #多个,要写在括号里
print("要拷贝的目录路径不存在!",e)except NameError:
print("变量不存在,未定义!")
except Exception as e:
print("出现了未知的异常:",e)
else:
print("没有出现异常!")
print("Done!")
#嵌套try...except...
try:
print("1")
#shutil.copy("e:\\sdsddfsdfsfds","e:\\")
try:
print(xxx)
except:
print("嵌套里面的未知异常!")
print("try里面的语句都执行完了!")
except (FileNotFoundError,TypeError) as e:
print("要拷贝的目录路径不存在!",e)
try:
1/0
except:
print("异常处理中也有异常了!")
except NameError:
print("变量不存在,未定义!")
except Exception as e:
print("出现了未知的异常:",e)
else: #try except 语句还有一个可选的else子句,如果使用这个子句,那么必须放在所有的except子句之后。这个子句将在try子句没有发生任何异常的时候执行
print("没有出现异常!")
print("Done!")
try-finally/else语句
➢在try块中抛出一个异常,程序会立即执行finally块代码(如果有的话)。当finally
块中的所有代码被执行结束后,异常才会被再次提出,并执行except块代码。
➢finally和else语句块可以同时存在。如果发生异常只执行finally语句块,否则两语
句块都会执行。
#encoding=utf-8
import sys
try:
s = input('Enter something --> ')
except KeyboardInterrupt:
print ('\nWhy did you do an Ctrl+c on me?') #ctrl+c
sys.exit() # exit the program
except:
print ('\nSome error/exception occurred.') #ctrl+z 报错
else:
print ("no exception occur!")
finally:
print ("finally is executed!") #注意:finally要放到else的后面,否则报语法错误
执行结果:
C:\Users\Administrator\Desktop>py -3 hello.py
Enter something --> e #输入e,else和finally下的语句都被执行
no exception occur!
finally is executed!
抛出异常
使用使用 raise 语句抛出一个指定的异常
>>>raise NameError('HiThere')
Traceback (most recent call last):
File "<stdin>", line 1, in ?
NameError: HiThere
raise 唯一的一个参数指定了要被抛出的异常。它必须是一个异常的实例或者是异常的类(也就是 Exception 的子类)。
如果你只想知道这是否抛出了一个异常,并不想去处理它,那么一个简单的 raise 语句就可以再次把它抛出。
>>>try:
raise NameError('HiThere')
except NameError:
print('An exception flew by!')
raise
An exception flew by!
Traceback (most recent call last):
File "<stdin>", line 2, in ?
NameError: HiThere
自定义异常
通过创建一个新的异常类,程序可以创建它们自己特定的异常。自定义异常都需
要继承异常基类(Exception类),当然也可以继承具体的异常类(比如
RuntimeError),通过直接或间接的方式。
# coding=utf-8
class Networkerror(RuntimeError):
# 重写默认的__init__()方法,
# 抛出特定的异常信息
def __init__(self, value):
self.value = value
# 触发自定义的异常
try:
raise Networkerror("Bad hostname")
except Networkerror as e:
print ("My exception occurred, value:", e.value)
异常抛出机制:
1、如果在运行时发生异常,解释器会查找相应的处理语句(称为handler)。
2、要是在当前函数里没有找到的话,它会将异常传递给上层的调用函数,看看
那里能不能处理。
3、如果在最外层(全局“main”)还是没有找到的话,解释器就会退出,同时打印
出traceback以便让用户找到错误产生的原因。
注意:
虽然大多数错误会导致异常,但一个异常不一定代表错误,有时候它们只是一个
警告,有时候它们可能是一个终止信号,比如退出循环等。