异常处理
一、什么是异常
异常就是程序运行时发生错误的信号(在程序出现错误时则会产生一个异常,若程序没有处理它,则会抛出异常,程序也会随之终止),在python中,错误触发的异常如下:
而错误分为两种
1.语法错误(这种错误,根本过不了python解释器的语法检查,必须在程序执行之前就改正)
# 语法错误示范一
if
# 语法错误示范二
def test:
pass
# 语法错误示范三
class Foo
pass
# 语法错误示范四
print(haha)
2.逻辑错误
# TypeError:int类型不可替代
for i in 3:
pass
# ValueError
num = input(">>:") # 输入hello
int(num)
# NameError
aaa
# IndexError
I = ['egon','a']
I[3]
# KeyError
dic = {'name':'egon'}
dic['age']
# AttributeError
class Foo:pass
Foo.x
# ZeroDivisionError:无法完成计算
res1 = 1/0
res2 = 1 + 'str'
二、异常的种类
在python中不同的类型可以用不同的类型(python中统一了类和类型,类型即类)去标识,一个异常标识一种错误。
常见异常
AttributeError :试图访问一个对象没有的属性,比如Foo.x,但是Foo没有属性x
IOError :输入/输出异常;基本上是无法打开文件
ImportError :无法导入模块或包;基本上是路径问题或名称错误
IndentationError :语法错误(的子类);代码没有正确对齐
IndexError :下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]
KeyError :试图访问字典里不存在的键
KeyboardInterrupt :Ctrl + C被按下
SyntaxError :Python代码非法,代码不能编译(个人认为是语法错误,写错了)
TypeError :传入对象类型与要求的不符合
UnboundLocalError :试图访问一个还未被设置的局部变量,基本上是由于另一个同名的全局变量,导致你以为正在访问它
ValueError :传入一个调用者不期望的值,即使值的类型是正确的
更多异常
异常名称 | 描述 |
---|---|
BaseException | 所有异常的基类 |
SystemExit | 解释器请求退出 |
KeyboardInterrupt | 用户中断执行(通常是输入^C) |
Exception | 常规错误的基类 |
StopIteration | 迭代器没有更多的值 |
GeneratorExit | 生成器(generator)发生异常来通知退出 |
StandardError | 所有的内建标准异常的基类 |
ArithmeticError | 所有数值计算错误的基类 |
FloatingPointError | 浮点计算错误 |
OverflowError | 数值运算超出最大限制 |
ZeroDivisionError | 除(或取模)零 (所有数据类型) |
AssertionError | 断言语句失败 |
AttributeError | 对象没有这个属性 |
EOFError | 没有内建输入,到达EOF 标记 |
EnvironmentError | 操作系统错误的基类 |
IOError | 输入/输出操作失败 |
OSError | 操作系统错误 |
WindowsError | 系统调用失败 |
ImportError | 导入模块/对象失败 |
LookupError | 无效数据查询的基类 |
IndexError | 序列中没有此索引(index) |
KeyError | 映射中没有这个键 |
MemoryError | 内存溢出错误(对于Python 解释器不是致命的) |
NameError | 未声明/初始化对象 (没有属性) |
UnboundLocalError | 访问未初始化的本地变量 |
ReferenceError | 弱引用(Weak reference)试图访问已经垃圾回收了的对象 |
RuntimeError | 一般的运行时错误 |
NotImplementedError | 尚未实现的方法 |
SyntaxError | Python 语法错误 |
IndentationError | 缩进错误 |
TabError | Tab 和空格混用 |
SystemError | 一般的解释器系统错误 |
TypeError | 对类型无效的操作 |
ValueError | 传入无效的参数 |
UnicodeError | Unicode 相关的错误 |
UnicodeDecodeError | Unicode 解码时的错误 |
UnicodeEncodeError | Unicode 编码时错误 |
UnicodeTranslateError | Unicode 转换时错误 |
Warning | 警告的基类 |
DeprecationWarning | 关于被弃用的特征的警告 |
FutureWarning | 关于构造将来语义会有改变的警告 |
OverflowWarning | 旧的关于自动提升为长整型(long)的警告 |
PendingDeprecationWarning | 关于特性将会被废弃的警告 |
RuntimeWarning | 可疑的运行时行为(runtime behavior)的警告 |
SyntaxWarning | 可疑的语法的警告 |
UserWarning | 用户代码生成的警告 |
三、异常处理
为了保障c的健壮性和容错性,即在遇到错误时程序也不会出现崩溃,我们需要对异常进行处理,如果错误发生的条件是可预知的,我们需要用if进行处理:在错误发生之前进行预防
AGE = 10
while True:
age = input('>>:').strip()
if age.isdigit(): #只有在age为字符串形式的整数时,下列代码才不会出错,该条件是可预知的
age = int(age)
if age == AGE:
print('you got it!')
break
如果错误发生的条件是不可预知的,则需要用到try……except:错误发生之后的处理
# 基本语法为
try:
被检测的代码块
except 异常类型:
try中一旦检测出异常,就执行这个位置的逻辑
# 举例
try:
age = input('>>:')
age = int(age)
except ValueError:
print('输入的不是数字!')
测试:
>>:a
输入的不是数字!
四、try……except:详细用法
1.异常类只能用来处理指定的异常情况,如果非指定异常则无法处理
s1 = 'hello'
try:
int(s1)
except IndexError as e: # 未捕获到异常,程序直接报错
print(e)
2.多分支
s1 = 'hello'
try:
int(s1)
except IndexError as e:
print(e)
except KeyError as e:
print(e)
except ValueError as e: # 捕捉到异常
print(e)
3.万能异常Exception
s1 = 'hello'
try:
int(s1)
except Exception as e: # 捕捉到异常
print(e)
4.也可以在多分支之后来一个Exception
s1 = 'hello'
try:
int(s1)
except IndexError as e:
print(e)
except KeyError as e:
print(e)
except ValueError as e: # 捕获到异常
print(e)
except Exception as e: # 捕获到异常
print(e)
5.异常的其他机构
s1 = 'hello'
try:
int(s1)
except IndexError as e:
print(e)
except KeyError as e:
print(e)
except ValueError as e:
print(e)
else:
print("try内代码块没有异常则执行我")
finally:
print("无论异常与否,都会执行该模块,通常是进行清理工作")
6.主动触发异常
try:
raise TypeError('类型错误')
except Exception as e:
print(e)
7.自定义异常
class DivException(BaseException):
def __init__(self,msg):
self.msg = msg
def __str__(self):
return self.msg
try:
raise DivException('自定义异常错误')
except DivException as e:
print(e)
8.断言:assert条件
assert 1 == 1
assert 1 == 2
测试
Traceback (most recent call last):
File "/media/martin/DCFC42C0FC429524/异常处理.py", line 147, in <module>
assert 1 == 2
AssertionError
9.总结
1. 把错误处理和真正的工作分开来
2. 代码更易组织,更清晰,复杂的工作任务更容易实现
3. 毫无疑问,更安全了,不至于由于一些小的疏忽而使程序意外崩溃了