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