Python3函数之装饰器

℡╲_俬逩灬. 提交于 2020-03-01 10:45:05

不带参数的装饰器

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
@zsq
def zzsc(): # 设计最终函数,也当做sc被装饰,这里百搭参数
    '''zzsc...'''
    print('sc function.')
    return 1 # 返回值

# 定义过程:
# 设计zzsc为被装饰函数,并作为输入函数参数被传入装饰器
# 装饰器封装一个函数,并传入百搭参数
# 装饰器返回封装函数,并把最终函数指向封装函数,
# 这时候最终函数的参数(百搭参数)
#执行过程:
# 调用最终函数,传入百搭参数
# 执行封装函数。。
# 执行被装饰函数
#PS:
# 装饰器的返回值肯定是封装函数
# 最终函数|被装饰函数的返回值,用于供封装函数可能使用
# 封装函数的返回值会成为最终函数的返回值被返回

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

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

  装饰器肯定是高阶函数

带参数的装饰器

import time
from functools import wraps
def 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 n
fun(3)

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

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

  带参数的装饰器多了一层

装饰器的应用

  cache

from functools import wraps
import time

class DictCache: # 缓存
    def __init__(self):
        self.cache = dict()
    
    def get(self, key):
        return self.cache.get(key)
        
    def set(self, key, value):
        self.cache[key] = value

def 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 dec

cache_instance = DictCache()

@cache(cache_instance)
def long_time_fun(x):
    time.sleep(x)
    return x

long_time_fun(3)

  第二次long_time_fun不会执行

  标准库已实现

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

  监控

from functools import wraps
import logging

class 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 x
long_time_fun(1)

身法验证 授权

from functools import wraps

def do_auth(info):
    # 通过header里的身份信息验证用户身份
    return True

def 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!