python 实现简单的CacheCallHandler装饰器
Python的functools模块, 提供了3个有趣函数, partial, update_wrapper 和wraps 。
partial函数,它可以重新绑定函数的可选参数,生成一个callable的partial对象。
update_wrapper函数,把被封装函数的__name__、__module__、__doc__和 __dict__都复制到封装函数去。
wraps函数,对update_wrapper更进一步封装。
可以利用wraps函数,实现简单的方法拦截机制,来实现自己的cacheCallHandler,
具体实现:
#-*- coding: UTF-8 -*- #------------------------------------------------------------------------------- # Name: 模块2 # Purpose: # # Author: ankier # # Created: 22-12-2012 # Copyright: (c) Ankier 2012 # Licence: <2012~2020> #------------------------------------------------------------------------------- import time import hashlib import pickle import sys from functools import wraps _Cache ={} def __HashParamsKey(function, args, kw): glos = function.func_globals package = glos['__package__'] model = glos['__name__'] methodName = function.func_name key = pickle.dumps((package, model, methodName, args, kw)) return hashlib.sha1(key).hexdigest() def __IsObsolete(entry, duration): return time.time() - entry['time'] > duration def CacheCallHandler(duration = sys.maxint): def _CacheCallHandler(fun): @wraps(fun) def wrap(args, kw): key = __HashParamsKey(fun, args, kw) if key not in _Cache or __IsObsolete(_Cache[key], duration): #保存结果 result = fun(args, kw) _Cache[key] = {'value': result, 'time': time.time()} return _Cache[key]['value'] return wrap return _CacheCallHandler
输出结果:
------sum----- 9 9
丰富CacheCallHandler的功能,加上cache过期策略。
实现:
#-*- coding: UTF-8 -*- #------------------------------------------------------------------------------- # Name: 模块2 # Purpose: # # Author: ankier # # Created: 22-12-2012 # Copyright: (c) Ankier 2012 # Licence: <2012~2020> #------------------------------------------------------------------------------- import time import hashlib import pickle import sys from functools import wraps _Cache ={} def __HashParamsKey(function, args, kw):
glos = function.func_globals
package = glos['__package__']
model = glos['__name__']
methodName = function.func_name
key = pickle.dumps((package, model, methodName, args, kw))
return hashlib.sha1(key).hexdigest()
def __IsObsolete(entry, duration): return time.time() - entry['time'] > duration def CacheCallHandler(duration = sys.maxint): def _CacheCallHandler(fun): @wraps(fun) def wrap(args, kw): key = __HashParamsKey(fun, args, kw) if key not in _Cache or __IsObsolete(_Cache[key], duration): #保存结果 result = fun(args, kw) _Cache[key] = {'value': result, 'time': time.time()} return _Cache[key]['value'] return wrap return _CacheCallHandler