不带参数的装饰器
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
来源:oschina
链接:https://my.oschina.net/u/2698055/blog/760719