异常在程序开发中是经常会遇到的。异常大体可以分成两类,一类是编译异常,主要是语法错误;另一类是运行异常。如果你使用pycharm等工具,那么语法错误会在你运行程序前就自动标注出来,也就是根本无法完成编译。而运行错误是在运行中可能会发生的错误。这种错误有时候并不能复现。典型的如网络请求错误。
1、python中常见的异常类
python中常见异常类
名称 | 解释 | BaseException | 所有异常的基类 | Exception | 常规错误的基类,自定义异常可以继承这个 | ZeroDivisionError | 除(或取模)零? | AttributeError | 对象没有这个属性 | IOError | 输入/输出异常 | ImportError | 导入模块/对象失败,没有安装依赖或版本问题 | IndexError | 下标越界 | KeyError | 字典中没有这个键 | ValueError | 传入无效的参数 | UnicodeDecodeError | Unicode 解码时的错误 | UnicodeEncodeError | Unicode 编码时错误 | DeprecationWarning | 新版本会弃用的警告 | FutureWarning | 新版本会改变的警告 | FileNotFoundError | 文件未找到,往往路径没写正确 | StopIteration | 迭代器没有更多的值 | KeyboardInterrupt | 用户中断执行 |
2、异常的一般处理
(1)try-except
user = {'name': '张三'}
try:
name = user['姓名']
except KeyError:
name = user['name']
print(name)
# 输出: 张三
(2)try-except-finally
finally的引入并非是必须的,很多时候只是为了让语义更明确。如下面这个例子,无论是否遇到异常,都会产生一名幸运观众。但需要注意,如果在函数里使用finally,可能会有其他意想不到的事。感兴趣可以查看另一篇文章Python return和finally避坑_Jiangugu的博客-CSDN博客
import random
user = ['张三', '李四']
try:
index = random.randint(1, 10)
name = user[index]
except IndexError:
name = '内部员工'
finally:
print('幸运观众是:' + name)
# 输出: 幸运观众是:内部员工
(3)多个except
使用多个except主要是因为事先不确定会有哪种异常,或者说希望不同的异常对应不同的操作。
user = {'name': '张三'}
keys = ['name', '姓名']
import random
try:
index = random.randint(0, 2)
key = keys[index]
name = user[key]
except IndexError:
print('数组下标越界')
except KeyError:
print('字典没有这个主键')
(4)多个try-except嵌套使用
from pandas import read_csv
f = 'xx.csv'
try:
data = read_csv(f, encoding='utf8')
except UnicodeDecodeError:
try:
data = read_csv(f, encoding='ansi')
except UnicodeDecodeError:
data = read_csv(f, encoding='gbk')
3、产生异常
(1) raise 抛出异常
有时候我们希望当某种情况发生,就抛出异常。如网络请求中,状态码不等于200,此时程序也不会报错。但返回的数据就不是我们想要的了,此时就应该是主动处理,抛异常是其中一种方案。
import requests
res = requests.get('xxx.com')
if res.status_code != 200:
raise ValueError('获取数据异常')
data = res.json()
?(2) 断言异常
def test(n):
assert n >= 0, 'n必须大于等于0'
return '我今年{}岁了'.format(n)
try:
test(-1)
except AssertionError as e:
print(e)
# 输出:n必须大于等于0
(3)自定义异常
class MyException(Exception):
def __init__(self, msg):
self.msg = msg
def __str__(self):
return self.msg + ' 2022/1/1'
def test(n):
if n < 0:
raise MyException('自定义异常')
try:
test(-1)
except MyException as e:
print(e)
# 输出:自定义异常 2022/1/1
4、补充
实际上,不管是python语言本身还是一些第三方库,在提供一些方法时,都有考虑可能会产生的异常。比如上面提到的KeyError,我们完全可以避免自己捕获异常。
user = {'name': 'Lily', 'age': 18}
# 找不到该主键时,返回默认值
phone = user.get('phone', 110)
print(phone)
# 输出:110
|