异常
异常就是程序运行时发生错误的信号,在程序出现错误时,则会产生一个异常,若程序没有处理它,则会抛出该异常,程序的运行也随之终止.
错误有两种:
语法错误--不按照程序的语法进行编写代码,这种错误,在程序执行前就会被发现.这种错误必须改正才能够运行程序.不存在处不处理这种错误的说法.
逻辑错误--程序运行起来后出错,导致程序崩溃
异常是程序运行时发生错误的信号,或者说是程序发生错误以后得到的结果.错误只有两种,但是异常的信号有很多种,标示了具体的错误发生的原因.
每一个异常分为三部分:Traceback异常追踪信息, 异常类型, 异常值.
Python中不同的异常用不同的异常类型表示,一个异常标识一种具体错误.
实际上,异常也是一个类,所有的异常都来自于Exception类.
主要的异常类型有:
异常名 | 异常内容 |
---|---|
AttributeError | 试图访问一个对象没有的属性,比如foo.x,但是foo没有属性x |
IOError | 输入/输出异常;基本上是无法打开文件 |
ImportError | 无法引入模块或包;基本上是路径问题或名称错误 |
IndentationError | 语法错误(的子类) ;代码没有正确对齐 |
IndexError | 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5] |
KeyError | 试图访问字典里不存在的键 |
KeyboardInterrupt | Ctrl+C被按下 |
NameError | 使用一个还未被赋予对象的变量 |
SyntaxError | 语法错误 |
TypeError | 传入对象类型与要求的不符合 |
UnboundLocalError | 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,导致你以为正在访问它 |
ValueError | 传入一个调用者不期望的值,即使值的类型是正确的 |
异常处理
python解释器检测到错误,或者程序员自行决定触发,都会触发异常.如果不处理,程序就会停止运行. 编写特定的代码,捕捉出现的异常,然后继续执行想要的逻辑,这就是异常处理,使程序不会崩溃.处理方式:
一 采用逻辑判断预先避免异常发生
如果预先知道异常可能发生的地方,则可以预先处理,可以采用各种分支条件来进行判断.但是如果针对可能出错的地方,都写一下与程序业务逻辑无关的判断,则代码的可读性很差,到处有大段的判断.
二 在异常发生之后进行处理.python为每一种异常定制了一个类型,并且用特定的语句去处理异常.
基本语句:
try:
被检测的代码块
except 异常类型:
try中检测到异常类型,就执行这个位置的逻辑
简单的例子:
try:
age = input('>>>')
int(age)
age2 = input('>>>')
int(age2)
except ValueError as er:
print(er)
try-except 多分支:
try:
age = input('>>>')
int(age)
age2 = input('>>>')
int(age2)
l = [1,2,3,4,5]
l[10]
except ValueError as er:
print(er.__str__())
except KeyboardInterrupt:
print(""don't press ctrl+c"")
except IndexError:
print(""越界了"")
except 如果不加具体的错误类型,则表示捕捉全部的错误.这样不是很好,因为可能无法确定异常的属性,一般比较好的做法是,依然打印出错误或者抛出错误.
万能异常还可以用Exception名来代替:
tag = True
while tag:
try:
age = input('>>>')
int(age)
age2 = input('>>>')
if age2 == 'quit':
break
int(age2)
except Exception as error:
print(error)
出错的时候显示出错的信息.
有时候如果程序没有出错,或者需要判断是否出错的情况下都有一定要执行的代码,try...except...语句还可以扩展成try...except...else...finally...逻辑:
try:
需要检测错误的代码块
except:
发生错误以后执行的逻辑
else:
没有发生错误后需要执行的代码块
finally:
无论是否异常,都执行该模块
注意,这些都是需要有try在最前边的时候出才能使用,平时不能单独使用.
自定义异常
所有的异常都来自于一个类叫Exception,只要继承这个类,就可以自定义自己的异常类型.
一般要定义一下__str__用来显示.异常定义的原理简单,但是实现起来比较复杂,以后可以慢慢研究.
一个典型的例子是:
class EgonException(BaseException):
def __init__(self,msg):
self.msg=msg
def __str__(self):
return self.msg
try:
raise EgonException('类型错误')
except EgonException as e:
print(e)
断言
assert 语句后边加上布尔表达式,表示当程序运行到这里时,一定满足后边表达式的为True的情况,如果不满足,则报错.这个经常用在某个关键点来判断一些重要的情况.
在程序出错完毕以后,应当将assert语句都去掉.
主动触发异常
raise 异常类型名 即可,还可以传入字符串赋给错误当做值显示.
raise IndexError('出错啦')