python中多个装饰器运行顺序

1.多个装饰器执行的顺序

通过一个例子来看:

def aa(f):
    print("this is a~")
    def wrapper(*args,**kwargs ):
        print("inner a")
        f(*args,**kwargs )
    return wrapper
def bb(fu):
    print("this is b~")
    def wrapper(*args,**kwargs ):
        print("inner b")
        fu(*args,**kwargs)
    return wrapper
@aa
@bb
def hh():
    print("hh~~~~~~~~~~")
hh()

运行结果:
this is b~
this is a~
inner a
inner b
hh~~~~~~~~~~

————————————————————————————————————————

通过断点debug发现其运行路径

  开始- -> inner a -->f()但未执行hh()-->inner b-->fu()执行了hh print()-->f()-->结束

由此可得:
@aa 在函数最外部,先执行aa装饰器的装饰;接着@bb,在执行bb装饰器的装饰;执行原函数本身
————————————————————————————————————————

结论

  • 装饰顺序 : 就近原则(包装)
    被装饰的函数,组装装饰器时,是从下往上装饰
  • 执行顺序 : 就远原则(拆包装)
    装饰器调用时是从上往下调用
    运行结果中的 this is b~ this is a~ 可以理解为包装的过程来向我们print

2.多个装饰器练习

需求:[‘root’,‘admin’,‘redhat’]
id id+vip
多个装饰器的应用场景:
会采用多个装饰器先验证是否登陆成功 再验证权限是否足够

import inspect
list_root=['root','admin','redhat']
def test_login(f):
    def inner(*args ,**kwargs ):
        if args[0] in list_root:
            res=f(*args,**kwargs )
            return res
        else:
            print("登录失败")

    return inner
def test_admin(fu):
    def wrapper(*args,**kwargs): ##多个类型参数传递时;内部函数名称必须为wrapper 否则 运行到inspect模块时会报错
        inspect_res = inspect.getcallargs(fu, *args, **kwargs)
        print(inspect_res )
        if inspect_res .get('name')=='root':
            rres=fu(*args,**kwargs)
            return rres
        else:
            print("Permission Deniy")
    return wrapper

@test_login
@test_admin
def fun(user):
    print("%s~~~~"%(user))

fun('admin')

运行结果:
{'user': 'admin'}
Permission Deniy
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值