python多个装饰器装饰同一个函数

一、装饰器作用

  1.装饰器可以实现,在不修改原来函数的代码时,进行功能的扩展。实现了代码的封装,同时扩展了功能,也不会重复执行。

二、多个装饰器修饰同一函数代码
# 闭包实现装饰器

def add_authorization(func):
	# 扩展的控制权限验证的代码
	print("*******开始执行装饰权限的功能******")
	def call_func(*args, **kwargs):
		print("*****验证权限*****")
		return func(*args, **kwargs)
	return call_func


def add_log(func):
	# 增加的记录日志的代码
	print("******开始装饰记录日志功能*******")
	def call_func(*args, **kwargs):
		print("*****日志*****")
		return func(*args, **kwargs)
	return call_func


@add_authorization
@add_log
def test(*args, **kwargs):
	# 原来的代码
	print("-------test-------")
	return "test is ok..."


if __name__ == "__main__":
	ret = test()
	print(f"ret = {ret}")

运行结果:

******开始装饰记录日志功能*******
*******开始执行装饰权限的功能******
*****验证权限*****
*****日志*****
-------test-------
ret = test is ok...

上面的add_authorization和add_log就是装饰器。用于装饰函数test。

三、代码解析

代码从上向下执行,执行到

@add_authorization
@add_log
  1. 先执行下面的装饰器add_log。
@add_log   # 等价于 test = add_log(test)
执行之后:
add_log.func = test
test = add_log.call_func

    add_log的形参add_log.func指向test函数指向的内存空间,可以理解为函数入口地址下次调用func时就是执行该空间的代码;之后test指向add_log.call_func引用的内存空间,即调用test时,就是执行该内存里的代码。
在这里插入图片描述
 2.在执行上面的装饰器add_authorization

@add_authorization  
# 表面上等价于 test = add_authorization(test)
# 实际上由于执行了add_log,导致test=add_log.call_func
# 实际上等价于 test = add_authorization(add_log.call_func)

执行之后:
add_authorization.func = add_log.call_func
test = add_authorization.call_func

3.综上可得:

add_log.func = test  # 3
add_authorization.func = add_log.call_func  # 2
test = add_authorization.call_func   # 1 

add_log.func指向了原来test指向的内存空间。add_authorization.func指向了add_log.call_func指向的内存空间。而test 指向了 add_authorization.call_func指向的内存空间。

所以调用test时,先去执行add_authorization.call_func的代码,之后在执行add_log.call_func的代码,最后再执行原来的test执行的代码。

在这里插入图片描述
总之,多个装饰器修饰同一个函数时,装饰的时候从下向上开始装饰。而调用的时候从上向下开始依次调用 执行代码。

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值