`

Python装饰器

阅读更多
编写自定义装饰器有许多方法,但最简单和最容易理解的方法是编写一个函数,返回封装原始函数调用的一个子函数。

通用的模式如下。
def my_decorator(function):
    def _my_decorator(*args, **kw):
        #在调用实际函数之前做些填充工作
        res = function(*args, **kw)
        #做完某些填充工作之后
        return res
    #返回子函数
    return _my_decorator

当装饰器需要参数时,必须使用第二级封装。
def my_decorator(arg1, arg2):
    def _my_decorator(function):
        def __my_decorator(*args, **kw):
            res = function()
            return res
        return __my_decorator
    return _my_decorator

引用
因为装饰器在模块第一次被读取时由解释程序装入,所以它们的使用必须受限于总体上可以应用的封装器。如果装饰器与方法的类或所增强的函数签名绑定,它应该被重构为常规的可调用对象,从而避免复杂性。在任何情况下,当装饰器处理API时,一个好的方法是将它们聚集在一个易于维护的模块中。

参数检查:
def check_param_isvalid():
    def check(method):
        def check_param(*args,**kwargs):
            for a in args:
                assert isinstance(a, int),"arg %r does not match %s" % (a,int)
                assert a > 100000,"arg %r must gt 100000" % a
            return method(*args, **kwargs)
        return check_param
    return check

@check_param_isvalid()
def foo(*args):
    print args

foo(200000,500000)

缓存:
import time
import hashlib
import pickle

cache = {}
def is_obsolete(entry, duration):
    return time.time() - entry['time'] > duration

def computer_key(function, args, kw):
    key = pickle.dumps((function.func_name, args, kw))
    return hashlib.sha1(key).hexdigest()

def memoize(duration=30):
    def _memoize(function):
        def __memoize(*args, **kw):
            key = computer_key(function, args, kw)
            if key in cache and not is_obsolete(cache[key], duration):
                print 'wo got a winner'
                return cache[key]['value']
            result = function(*args, **kw)
            cache[key] = {'value':result,'time':time.time()}
            return result
        return __memoize
    return _memoize

@memoize()
def very_complex_stuff(a,b):
    return a + b

print very_complex_stuff(2,2)


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

class Unauthorized(Exception):
    pass

def protect(role):
    def _protect(function):
        def __protect(*args, **kw):
            user = globals().get('user')
            if user is None or role not in user.roles:
                raise Unauthorized("I won't tell you")
            return function(*args, **kw)
        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()
user = tarek
these_are.waffle_recipe()
user = bill
these_are.waffle_recipe()

上下文提供者
from threading import RLock
lock = RLock()

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

@synchronized
def thread_safe():
    print 'haha'
   
thread_safe()


补充:http://2057.iteye.com/blog/1838398
参考资料:
Python高级编程
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics