Python闭包-装饰器


写在前面🐸

  • python的装饰器是一种语法糖,是在不改变原有代码的前提下进行 追加新功能,如:登陆鉴权…
  • 装饰器由闭包实现

闭包🧅

  • 闭包三要素
    • 1.函数嵌套, 即外部函数嵌套一个内部函数;
    • 2.外部函数返回内部函数引用;
    • 3.内部函数使用外部函数的变量或者形参
  • 闭包范例
    def out(func):
    	variable = 'This is out variable'
    	def inner():
    		print(variable)
    		func()
    	return inner
    

函数装饰器🧅

  • 1 简单装饰器
    import functools
    
    def  out(func):
    	@functools.wraps(func)
    	def inner(*args, **kwargs):
    		return func(*args, **kwargs)
    	return inner
    
    @out
    def func(*args, **kwargs):
       pass
       return 
    
  • 2 带参数的装饰器
    == 常见如 FastApi Flask 等定义接口的方式便是采用这种带参数的装饰器来规定请求方式的==
    import functools
    
    def Out(*args, **kwargs):
    	def out(func):
    		@functools.wraps(func)
    		def inner(*args, **kwargs):
    			return func()
    		return inner
    	return out
    
    # 常见的 如 FastApi Flask 等定义接口的方式便是采用这种带参数的装饰器来规定请求方式的
    @Out('post')
    def func():
    	pass
    		
    
  • 3 函数装饰器应用实例
    我们定义一个登录和鉴权装饰器来装饰api
    # 1.定义登录认证装饰器
    import functools
    
    
    def authenticated(func):
        @functools.wraps(func)
        def inner1(*args, **kwargs):
            print('登录认证代码')
            res = func(*args, **kwargs)
            print('登录认证后执行')
    
            return res
        return inner1
    
    
    # 2.定义鉴权装饰器
    def accesstoken(func):
        @functools.wraps(func)
        def inner2(*args, **kwargs):
            print('鉴权代码')
            res = func(*args, **kwargs)
            print('鉴权后执行')
            return res
    
        return inner2
    
    
    @authenticated
    @accesstoken
    def api():
        print('api逻辑')
        return
    
    
    api()
    

类装饰器🐚

类装饰器比之函数装饰器更好理解

  • 1 简单装饰器
    class Decorator():
        def __init__(self, func):
            self._func = func
    
        def __call__(self, *args, **kwargs):
            return self._func(*args, **kwargs)
    
    
    @Decorator
    def func(x):
        return x
    
  • 2 带参数的装饰器
    import functools
    
    
    class Decorator():
        def __init__(self, method=None):
            self._method = method
    
        def __call__(self, func):
            @functools.wraps(func)
            def wrapper(*args, **kwargs):
                return func(*args, **kwargs)
            return wrapper
    
    
    @Decorator('post')
    def func(x):
        return x
    
  • 3 类装饰器应用实例
    pass

大白话理解:

参考洋葱纹路,先从外到内再从内到外, 被装饰函数上层的代码属于从外到内, 被装饰函数下层的代码属于从内到外
我们以上面的函数装饰器实例为例:

  • api定义好后,此时装饰器函数立即执行,自下而上装饰api, 即 api= authenticated(accesstoken(api)) 拆解开来有如下步骤

    1. api = accesstoken(api) --> inner2
    2. api = authenticated(inner2) --> inner1
      此时的 api为装饰后的 api
  • 调用 api, 此时有如下调用链
    新api() --> inner1() [登录认证代码执行] - inner2() [鉴权代码执行] - api()[此时的api函数才是真正的初始定义的api] - 鉴权后执行 - [登录认证后执行], 如下
    在这里插入图片描述

    可以看到整个调用链有如洋葱纹理一样 自外而内自内而外

结论🐒

  • 一般的装饰器在装饰api函数时登录验证在上 鉴权在下, 意即, 先登录 再 鉴权
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值