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
原文地址:https://www.cnblogs.com/ankier/p/2828932.html