python 多个装饰器组合应用,实现面向切面之AOP编程
首先,需要对上面几篇介绍的2个callHandler (PerformanceCountCallHandler, CacheCallHandler)进行改写。
代码如下:
#-*- coding: UTF-8 -*- #------------------------------------------------------------------------------- # Name: 模块2 # Purpose: # # Author: ankier # # Created: 22-12-2012 # Copyright: (c) Ankier 2012 # Licence: <2012~2020> #------------------------------------------------------------------------------- import time from functools import wraps _Cache ={} def PerformanceCountCallHandler(): def _PerformanceCountCallHandler(originalFunc): def __PerformanceCountCallHandler(fun): def wrap(args, kw): glos = originalFunc.func_globals package = glos['__package__'] model = glos['__name__'] methodName = originalFunc.func_name timeStart = time.time() result = fun(args, kw) timeEnd = time.time() print 'package:',package,' , model:', model, ' , methodName:',methodName,'. ', timeEnd - timeStart, 's' return result return wrap return __PerformanceCountCallHandler return _PerformanceCountCallHandler
#-*- 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(originalFunc): def __CacheCallHandler(fun): def wrap(args, kw): key = __HashParamsKey(originalFunc, 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 return _CacheCallHandler
需要一个管理和注册多种装饰器的注册装饰器。
#-*- coding: UTF-8 -*- #------------------------------------------------------------------------------- # Name: registerDecorators # Purpose: # # Author: ankier # # Created: 23-12-2012 # Copyright: (c) Ankier 2012 # Licence: <2012~2020> #------------------------------------------------------------------------------- def RegisterDecorators(*_decorators): def _RegisterDecorators(func): wrap = func for _deco in _decorators: __deco = _deco(func) wrap = __deco(wrap) return wrap return _RegisterDecorators
下面看如何使用这些类,cache 在前面, performance handler 在后面。
使用方式如下:
#-*- coding: UTF-8 -*- import time from performanceCountCallHandler import PerformanceCountCallHandler from cacheCallHandler import CacheCallHandler from registerDecorators import RegisterDecorators @RegisterDecorators(CacheCallHandler(10000), PerformanceCountCallHandler()) def Sum(xx , yy ): sum = xx + yy print '------Execute Sum----- ' time.sleep(5) return sum @RegisterDecorators(CacheCallHandler(1), PerformanceCountCallHandler()) def Count(xx , yy ): sum = xx + yy print '------Execute Count----- ' time.sleep(5) return sum
运行效果:
------Execute Sum----- package: None , model: mainFrame , methodName: Sum . 5.0 s 9 package: None , model: mainFrame , methodName: Sum . 0.0 s 9 ------Execute Count----- package: None , model: mainFrame , methodName: Count . 5.0 s 2 ------Execute Count----- package: None , model: mainFrame , methodName: Count . 5.0 s 3 ------Execute Count----- package: None , model: mainFrame , methodName: Count . 5.01600003242 s 2