荐 python装饰器记录日志、异常处理、函数功能添加
python装饰器作用实例
为什么需要使用装饰器?
举一个简单的例子:
当你需要记录一个函数整个处理过程的时间,你会怎么做?最简单直观的方法,当然是在函数开始跟结束的地方记录时间。代码如下:
import time
def action():
start_time = time.time()
# 业务逻辑流程开始
time.sleep(1)
# 业务逻辑流程结束
# 计算总时间
print('action 处理时间:%s' % (time.time()-start_time))
action 处理时间:1.0000574588775635
但是,我嘚告诉你,实际情况是你要统计多个业务函数的耗时;你要怎么办?你完全可以选择复制粘贴进每个函数的头部跟尾部,但等你终于费大劲粘贴完之后,业务需求又告诉你,时间格式得限制一下,这时候你是不是要崩溃了?有没有什么取而代之的东西,实现这一功能呢?有,那就是装饰器。
装饰器的作用-记录程序时间
顾名思义,装饰,是对某样东西,进行加工修饰;抽象成代码思维,就是对代码里的对象,不改变其本身功能而进行二次加工;像上面的例子,我们可以利用装饰器在原有的函数基础上,进行时间统计。(装饰器本质也是一个函数,原理利用了闭包思维,可自行百度闭包)
import time
# 利用装饰器统计函数时间
# 编写装饰器
def count_time(func):
def decorate(*args, **kwargs):
start_time = time.time()
# func为被装饰函数
func(*args, **kwargs)
end_time = time.time()
print('函数 处理时间:%s' % (end_time-start_time))
return decorate
# 业务函数,增加装饰器统计时间
@count_time # 利用语法糖 @ 调用装饰器
def action():
# 执行业务
print('执行业务函数...')
time.sleep(1)
print('执行业务函数结束')
# 运行业务函数
action()
执行业务函数…
执行业务函数结束
函数 处理时间:1.0000572204589844
可以看到,原有函数功能并未改变,在函数外层实现了统计时间功能。如果难以理解语法糖@这种方式,可以使用函数调用的方式尝试:
count_time(action())
执行业务函数…
执行业务函数结束
函数 处理时间:1.0000572204589844
装饰器的作用-异常处理
一个捕获异常的简单例子:
def catch_exc():
try:
print(1/0)
except Exception():
# 异常处理程序
exc_handler()
当函数中有多处不确定异常需要处理,难道要在每一处进行异常捕获?不会,这样不仅让代码显得臃肿,还难以维护。通常明智的做法是不在函数内部进行异常处理,而是在函数外部进行一些已知或未知异常捕获。
# 定义自定义异常
class DIYException(Exception):
def __init__(self, err_msg):
self.err_msg = err_msg
# 定义异常输出
def __str__(self):
return "[DIYException] %s" % self.err_msg
# 定义erpr输出
def __erpr__(self):
return self.err_msg
# 定义异常捕获处理装饰器
def exc_handler(func):
def catch_exc(*args, **kwargs):
try:
return func(*args, **kwargs)
# 捕获自定义异常进行处理
except DIYException:
# return DIYException_handler()
return "捕获到自定义异常"
# 捕获键值异常进行处理
except KeyError:
# return keyerror_handler()
return "捕获到键值异常"
# 捕获未知异常进行处理
except BaseException:
# return baseerror_handler()
return "捕获到其他异常"
return catch_exc
# 定义功能函数 并用异常处理函数装饰
@exc_handler
def action_normal():
return "正常函数返回"
@exc_handler
def action_diyerror():
raise DIYException("抛出自定义异常")
@exc_handler
def action_keyerror():
a = {}
print(a["nonekey"]) # 抛出KeyError
@exc_handler
def action_elseexception():
print(1/0) # 抛出其他异常
print(action_normal())
print(action_diyerror())
print(action_keyerror())
print(action_elseexception())
正常函数返回
捕获到自定义异常
捕获到键值异常
捕获到其他异常
上面就是利用装饰器对异常处理的简单基本操作。
理解了装饰器的基本原理,处理日常需求更加轻便快捷.
作者:十八
本文地址:https://blog.csdn.net/eightTeen/article/details/107173954