侧边栏壁纸
博主头像
落叶人生博主等级

走进秋风,寻找秋天的落叶

  • 累计撰写 130562 篇文章
  • 累计创建 28 个标签
  • 累计收到 9 条评论
标签搜索

目 录CONTENT

文章目录

Python3函数之装饰器

2023-12-16 星期六 / 0 评论 / 0 点赞 / 121 阅读 / 5140 字

不带参数的装饰器 from functools import wraps # 封装函数进行装饰,保留被装饰函数属性def zsq(sc): # 设计一个装饰器函数,传入被装饰函数 @wraps(

不带参数的装饰器

from functools import wraps # 封装函数进行装饰,保留被装饰函数属性def zsq(sc): # 设计一个装饰器函数,传入被装饰函数    @wraps(sc)    def nsc(*args, **kwargs): # 设计它的封装        jg = sc(*args, **kwargs) # 调用被装饰函数,配合百搭        print('nsc function.')        print(jg)        return 0    return nsc@zsqdef zzsc(): # 设计最终函数,也当做sc被装饰,这里百搭参数    '''zzsc...'''    print('sc function.')    return 1 # 返回值# 定义过程:# 设计zzsc为被装饰函数,并作为输入函数参数被传入装饰器# 装饰器封装一个函数,并传入百搭参数# 装饰器返回封装函数,并把最终函数指向封装函数,# 这时候最终函数的参数(百搭参数)#执行过程:# 调用最终函数,传入百搭参数# 执行封装函数。。# 执行被装饰函数#PS:# 装饰器的返回值肯定是封装函数# 最终函数|被装饰函数的返回值,用于供封装函数可能使用# 封装函数的返回值会成为最终函数的返回值被返回

  装饰器的本质是函数,接收一个函数作为参数,并且返回一个函数

  装饰器通常会返回一个封装函数,这个封装函数在传入的函数前后做一些修饰

  装饰器肯定是高阶函数

带参数的装饰器

import timefrom functools import wrapsdef timeit(cpu_time=False):    time_func = time.clock if cpu_time else time.time    def dec(fn):        @wraps(fn)        def wrap(*args, **kwargs):            start = time_func()            ret = fn(*args, **kwargs)            print(time_func() - start)            return ret        return wrap    return dec
@timeit()def fun(n):    time.sleep(n)    return nfun(3)

@timeit(True)def fun(n):    time.sleep(n)    return nfun(3)

  带参数的装饰器是一个函数,返回一个装饰器

  带参数的装饰器多了一层

装饰器的应用

  cache

from functools import wrapsimport timeclass DictCache: # 缓存    def __init__(self):        self.cache = dict()        def get(self, key):        return self.cache.get(key)            def set(self, key, value):        self.cache[key] = valuedef cache(instance): # 缓存装饰器    def dec(fn):        @wraps(fn)        def wrap(*args, **kwargs):            pos = ','.join((str(x) for x in args))            kw = ','.join('{}={}'.format(k, v) for k, v in sorted(kwargs.items()))            key = '{}::{}::{}'.format(fn.__name__, pos, kw) # 拼装key,第一次存入缓存            ret = instance.get(key)            if ret is not None: # 检查缓存是否已有                return ret            ret = fn(*args, **kwargs) # 未缓存,执行            instance.set(key, ret)            return ret        return wrap    return deccache_instance = DictCache()@cache(cache_instance)def long_time_fun(x):    time.sleep(x)    return xlong_time_fun(3)

  第二次long_time_fun不会执行

  标准库已实现

from functools import lru_cacheimport time@lru_cache()def long_time_fun(x):    time.sleep(x)    return xlong_time_fun(3)

  监控

from functools import wrapsimport loggingclass LoggingMetric:    def send(self, key, value):        longging.warning('{} => {}'.format(key, value))def mertic(prefix, instance):    def timeit(fn):        @wraps(fn)        def wrap(*args, **kwargs):            start = time.time()            ret = fn(*args, **kwargs)            key = '{}.{}.{}'.format(prefix, fn.__module__, fn.__name__)            print(key)            return ret        return wrap    return timeit@mertic(prefix='chalotte', instance=LoggingMetric())def long_time_fun(x):    time.sleep(x)    return xlong_time_fun(1)

身法验证 授权

from functools import wrapsdef do_auth(info):    # 通过header里的身份信息验证用户身份    return Truedef auth(header_name):    def dec(fn):        @wraps(fn)        def wrap(request):            info = request.headers.get(header_name)            if do_auth(info):                return fn(request)            return AccessDenied()        return wrap    return dec@auto('X-Auth-Info')def handle(request):    pass# 设定

路由

github.com/pallets/flask/blob/master/flask/app.py

广告 广告

评论区