首页 > 代码库 > python 装饰器与AOP

python 装饰器与AOP

无高见


1.缓存

from functools import wraps

lineseq = '==' * 20

def memo( func ):
    
    cache = {}

    @wraps( func )
    def wrapper( *args ):
        result = cache.get( args )
        if result is None:
            result = func( *args )
            cache[args] = result
        return result

    return wrapper


@memo
def fib( n ):
    if n < 2:
        return n
    return fib( n - 1 ) + fib( n - 2 )

print fib( 10 )


2.注册函数信息

import time

def logger( func ):
    
    @wraps( func )
    
    def deco( *args, **kwargs ):
        start_time = time.time()
        result = func( *args, **kwargs )
        end_time = time.time()
        print 'function = {0}'.format( func.__name__ )
        print 'arguments = {0}{1}'.format( args, kwargs )
        print 'return = {0}'.format( result )
        print 'time = %.6f sec'%( start_time - end_time )
        return result
    return deco


@logger
def sum_num( a, b, c ):
    return a + b + c


3.参数检查

from itertools import izip

rpc_info = {}

def xmlrpc( in_args = (), out_args = ( type( None ), ) ):

    def _check_types( elements, types ):
        if len( elements ) != len( types ):
            raise TypeError( 'argument count is wrong' )
        typed = enumerate( izip( elements, types ) )
        for index, couple in typed:
            arg, type_ = couple
            if isinstance( arg, type_ ):
                continue
            raise TypeError( 'arg %d should be %s'%( index, type_ ) )

    
    def _xmlrpc( func ):
        function_name = func.__name__
        rpc_info[function_name] = ( in_args, out_args )
        
        def __xmlrpc( *args ):
            check_args = args[1:]
            _check_types( check_args, in_args )
            result = func( *args )
            if not type( result ) in ( tuple, list ):
                check_results = ( result, )
            else:
                check_results = result
            _check_types( check_results, out_args )
            return result

        return __xmlrpc
        
    return _xmlrpc



class RPCView( object ):

    @xmlrpc( ( int, int ) )
    def method1( self, int_a, int_b ):
        print 'recevied %d and %d'%( int_a, int_b )

    @xmlrpc( ( str, ), ( int, ) )
    def method2( self, info ):
        print 'received %s'%( info )
        return 0

    
a = RPCView()
a.method1( 12, 21 )


4.代理

class User( object ):
    def __init__( self, role ):
        self.roles = role

class Unauthorized( Exception ):
    pass


def protect( role ):
    def _protect( function ):
        def __protect( *args, **kwargs ):
            user = globals().get( 'user' )
            if user is None or role not in user.roles:
                raise Unauthorized( 'I will not tell you' )
            return function( *args, **kwargs )
        return __protect
    return _protect

tarek = User( ( 'admin', 'user' ) )
bill = User( ( 'user', ) )

class MySecrets( object ):

    @protect( 'admin' )
    def waffle_recipe( self ):
        print 'use tons of butter!'


these_are = MySecrets()
#these_are.waffle_recipe()

user = tarek
these_are.waffle_recipe()

these_are = bill
these_are.waffle_recipe()


5.上下文提供者

from threading import RLock

lock = RLock()

def synchronized( function ):
    def _synchronized( *args, **kwargs ):
        lock.acquire()
        try:
            return function( *args, **kwargs )
        finally:
            lock.release()
    return _synchronized


@synchronized
def thread_safe():
    pass