【Python上手】错误类型与异常捕获

# 异常层级关系

下面的图展示了Python中各种异常类的层级关系,可以发现,他们都是继承自BaseException类。

在这里插入图片描述

# 6种常见异常
  1. 除0错误(ZeroDivisionError):除数为0
  2. 名称错误(NameError):变量使用之前未进行声明或者初始化
  3. 类型错误(TypeError):某些函数或者方法只适用于特定数据类型,若数据类型操作不当会报此错
  4. 数值错误(ValueError):输入类型正确的情况下,具体输入数值错误
  5. 索引错误(IndexError):超出序列长度的索引操作
  6. 属性错误(AttributeError):方法或者属性不适用于该对象
# 除0错误(ZeroDivisionError)
num = 3
num / 0

# 名称错误(NameError)
variable_a

# 类型错误(TypeError)
num = 3
num + '3'

# 数值错误(TypeError)
float('3')
float('hackdata')

# 索引错误(TypeError)
hack_list = ['h', 'a', 'c', 'k']
hack_list[10]

# 属性错误
tuple_hack = ('h', 'a', 'c')
tuple_hack('k')

为了防止程序因出现异常而停止执行,我们要对可能出现的异常提前预警并设置相应的处理方案,这就是异常的捕获。

# 异常的捕获

主要通过try...except...语句来实现异常捕获。将可能出现错误的代码块放在try中,except则根据多种错误类型设置异常处理方案。以下是例子:

try: 
	# 正常运行
except Exception1 as e:
	# 发生Exception1时的处理方式
except Exception2 as e:
	# 发生Exception1时的处理方式
else:
	# 正确时候执行
finally:
	# 无论对错都执行
# 异常的抛出

除了代码出错的时候触发错误,我们也可以主动控制抛出异常,通常使用关键词raise来实现。

raise ValueError('This is a value error')
# 自定义异常

当然,python中内建异常类无法覆盖所有异常情况,我们需要根据可能产生的特定错误自定义异常。自定义异常继承于Exception类,由它开始扩展。下面是一个简单示例:

class MyError(Exception):
	pass
raise MyError(u'something error')

"""
	示例:自定义NotIntError,捕获非整型错误
"""
class NotIntError(Exception):
	def __init__(self, error):
		self.error = error

a = [1, 2, "", 4, 5, "a", ['1', '2', '3']]

for i in range(len(a)):
	try:
		if type(a[i]) != int:
			raise NotIntError("错误")
	except NotIntError, e:
		print e.error
	finally:
		print a[i]
		

一个完整的使用自定义异常捕获的例子

# 第一步:定义异常
class Error(Exception):
	pass

class OpenFileError(Error):
	pass

class WriteContentError(Error):
	pass

def write(content):
	if isinstance(content, str):
		f = open('file.txt', 'w')
		try:
			f.write(content)
		except Exception:
			raise WriteContentError  # 抛出写入异常
		finally:
			f.close()
	else:
		raise OpenFileError  # 抛出打开异常


# 第二步,调用代码
import logging
try:
	write(2)
except OpenFileError as e:  # 对抛出异常的处理
	logging.error(e)
except WriteContentError as e:  # 对抛出异常的处理
	logging.error(e)
except Error:
	logging.error("API Error")
except Excetpion:
	logging.error("API Bug")
else:
	logging.info("ok")
# 一些经验
  • 只处理你知道的异常,避免捕获所有异常然后吞掉他们
  • 抛出的异常要说明原因,有时候知道异常类型也不知道具体缘由
  • 不要使用异常来控制流畅,这样很难维护
  • 如果有必要,切记要使用finally来释放资源

关于第3点,我们可以来看一个例子:

# 异常处理破坏了代码逻辑
try:
	action_a()
	action_b()
	action_c()
except ActionExceptin as e:
	logging.error(e)
else:
	action_d()


# 更优雅的处理方式,将异常代码块抽离到另外一个函数中
def action_executor():
	action_a()
	action_b()
	action_c()

def action():
	try:
		action_executor()
	except ActionExceptin as e:
	logging.error(e)

action()
action_d()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值