欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

荐 python装饰器记录日志、异常处理、函数功能添加

程序员文章站 2022-03-31 11:17:08
python装饰器作用实例为什么需要使用装饰器?装饰器的作用-记录程序时间装饰器的作用-异常处理为什么需要使用装饰器?举一个简单的例子:当你需要记录一个函数整个处理过程的时间,你会怎么做?最简单直观的方法,当然是在函数开始跟结束的地方记录时间。代码如下:import timedef action():start_time = time.time()# 业务逻辑流程开始time.sleep(1)# 业务逻辑流程结束# 计算总时间print('action 处理时间:%s'...

为什么需要使用装饰器?

举一个简单的例子:
当你需要记录一个函数整个处理过程的时间,你会怎么做?最简单直观的方法,当然是在函数开始跟结束的地方记录时间。代码如下:

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