异常
一、什么是异常
异常 是程序运行时发生错误的信号,每当发生让Python不知所措的错误时,都会创建一个创建一个异常对象。若异常未处理,程序将停止运行,并显示一个Traceback
n = "elk"
# n 保存的是 "elk" ,再将它转换成int时,将抛出一个异常
int(n)
以下为运行结果:
二、常见异常
AttributeError 试图访问一个对象没有的属性,比如foo.x,但是foo没有属性x
IOError 输入/输出异常;基本上是无法打开文件
ImportError 无法引入模块或包;基本上是路径问题或名称错误
IndentationError 语法错误(的子类) ;代码没有正确对齐
IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]
KeyError 试图访问字典里不存在的键
KeyboardInterrupt Ctrl+C被按下
NameError 使用一个还未被赋予对象的变量
SyntaxError Python代码非法,代码不能编译(个人认为这是语法错误,写错了)
TypeError 传入对象类型与要求的不符合
UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,导致你以为正在访问它
ValueError 传入一个调用者不期望的值,即使值的类型是正确的
三、异常处理
编写特定代码,捕捉异常,若捕捉成功,进入另一个处理分支,执行定制逻辑,使程序不会崩溃
(一)若异常发生的条件可预知,可使用 if 处理
num =10
while True:
n = input(">>>")
if n.isdigit(): #只有当输入的是数字时,才运行 if 中的代码块
n = int(n)
if n == num:
print("You guessed right.")
break
else:
print("Input error, please re-enter")
(二)若异常发生的条件未可知,可使用try…except
(1)基本语法
- 基本语法
try:
被检测代码块
except 异常类型:
try中一旦检测到异常,将执行此处的逻辑
- 举例
try:
n = input(">>>")
int(n) # 1
except ValueError: # 2
print("Input error")
print("Over") #3
检测用户的输入,如果用户输入正确,将不会引发异常,Python将跳过Except 代码块,执行后面的代码,本例即 3处。
如果用户输入的不是数字,在1处 将引发一个ValueError异常,然后将执行except 中的代码块。
(2)多分支
被检测代码可能会引发多个异常,这时候可以使用多分支
try:
n = input(">>>")
int(n) #1
print("-"*10)
li = [i for i in range(10)]
print(li[10]) #2
print("*"*10) #3
except ValueError as V:
print(V)
except IndexError as I:
print(I)
except NameError as N:
print(N)
print("Over")
在 2处 索引超出边界,将引发一个IndexError异常
值得注意的是,在2处引发了一个IndexError异常, 3 处 的代码将不会执行。
此外,异常类只能用来处理指定的异常类型,而非指定异常将无法处理。
(3)万能异常Exception
异常类型很多对于某些我们不需要指定处理逻辑的异常,可以使用Exception
try:
n = "elk"
int(n)
except Exception as E:
print(E)
可以在多分支后面加一个Exception
(4)else代码块
当 try 中的代码块没有引发异常,将执行 else中的代码块
try:
li = [i for i in range(10)]
li[0]
except IndexError as I:
print(I)
except Exception as E:
print(E)
else: #没有异常执行
print("OK")
在 try代码块 中未引发异常,执行 else,打印 Ok。
(5)finally代码块
被检测代码无论是否引发异常,都会执行 finally 中的代码块
try:
li = [i for i in range(10)]
li[0]
except IndexError as I:
print(I)
except Exception as E:
print(E)
finally: #无论是否有异常都将执行
print("hello")
try:
li = [i for i in range(10)]
li[10]
except IndexError as I:
print(I)
except Exception as E:
print(E)
finally: #无论是否有异常都将执行
print("hello")
两次执行结果都将打印 hello。
(6)主动触发异常
异常也可以被主动触发
#主动触发异常
try:
raise TypeError('类型错误')
except Exception as E:
print(E)
(7)自定义异常
#自定义异常
class ElkException(BaseException):
def __init__(self,msg):
self.msg=msg
try:
raise ElkException('类型错误')
except ElkException as e:
print(e)
(8)断言:assert
#断言:assert 条件
assert 1 == 1
assert 1 == 2 #1不等于2,将引发一个异常
(9)总结 try…except
1:把错误处理和真正的工作分开来
2:代码更易组织,更清晰,复杂的工作任务更容易实现;
3:更安全,不至于由于一些小的疏忽而使程序意外崩溃了。