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

装饰器概念,有什么功能,及业务场景?

程序员文章站 2022-04-06 16:42:59
...

概念:

1.装饰器的实现是由闭包支撑的;

2.装饰器本质上是⼀个python函数,它可以在让其他函数在不需要做任何代码的变动的前提下增加额外的功能;

3.装饰器的返回值也是⼀个函数的对象,它经常用于有切面需求的场景,实现路由传参,flask的路由传参依赖于装饰器,浏览器通过url访问到装饰器的路由,从而访问视图函数获得返回的HTML页面;

应用场景:

1.可以在外层函数加上时间计算函数,计算函数运行时间;

2.计算函数运行次数;

3.可以用在框架的路由传参上;

4.插入日志,作为函数的运行日志;

5.事务处理,可以让函数实现事务的一致性,让函数要么一起运行成功,要么一起运行失败;

6.缓存,实现缓存处理;

7.权限的校验,在函数外层套上权限校验的代码,实现权限校验;

 

写出一个单例的装饰器(使一个本来不是单例类的类变成单例类))

[python] view plain copy
  1. def set_func(func):  
  2.     __singleton = None  
  3.   
  4.     def call_func(*args, **kwargs):  
  5.         nonlocal __singleton  
  6.         if not __singleton:  
  7.             __singleton = func(*args, **kwargs)  
  8.             return __singleton  
  9.         else:  
  10.             return __singleton  
  11.     return call_func  
  12.  
  13.  
  14. @set_func  
  15. class Std(object):  
  16.   
  17.     def __init__(self, name, age):  
  18.         self.name = name  
  19.         self.age = age  
  20.   
  21.   
  22. s2 = Std('jack',18)  
  23. print(id(s2),s2.name,s2.age)  
  24.   
  25. s1 = Std('leo',23)  
  26. print(id(s1),s1.name,s1.age)  

运行结果:

[python] view plain copy
  1. 139727292442832 jack 18  
  2. 139727292442832 jack 18  

上下文提供者(Context Provider)

上下文装饰器被用来确保函数在正确的上下文环境运行,或者确保在函数运行前和运行后执行一些代码。换言之,该装饰器进行设置或取消设置某个特定的运行环境。例如,当一条数据要在多个线程之间共享时,就需要使用锁(lock)来确保数据被保护,以防出现并发访问。锁能够像下面这样放在装饰器

上下文装饰器,通常被上下文管理器(with 语句)取代。
from threading import RLock
lock = RLock()
def synchronized(function):
    def _synchronized(*args, **kw):
        lock.acquire()
        try:
            return function(*args, **kw)
        finally:
            lock.release()
    return _synchronized
 
@synchronized
def thread_safe(): # make sure it locks the resource
    pass

登录判断装饰器:

    之前做过的一个用flask框架实现的移动app项目,里面大量用到是否已经登录的判断,如果这个业务逻辑大量重复地写在视图函数,代码的复用性很差,因此我将登录判断封装成装饰器,然后用这个装饰器装饰每一个需要验证是否登录的视图函数,代码如下:


[python] view plain copy
  1. def login_required(view_func):  
  2.     """自定义装饰器判断用户是否登录"""  
  3.  
  4.     @wraps(view_func)  
  5.     def wrapper(*args, **kwargs):  
  6.         """具体实现判断用户是否登录的逻辑"""  
  7.         user_id = session.get('user_id')  
  8.         if not user_id:  
  9.             return jsonify(errno=RET.SESSIONERR, errmsg='用户未登录')  
  10.         else:  
  11.             g.user_id = user_id  
  12.             return view_func(*args, **kwargs)  
  13.   
  14.     return wrapper  
    总结:装饰器是python三大神器(迭代器,生成器,装饰器)中比较难理解的,但是它的本质实际上就是闭包,我们在闭包函数或者类外面封装了一套逻辑,因此可以增强函数的功能,增加权限校验,事务一致性,缓存等功能,这就是装饰器,使漂亮的姑娘(函数)变得更加漂亮。