Python装饰器

巴扎黑
巴扎黑 原创
2016-12-08 11:12:15 910浏览

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

通用的模式如下。

Python代码

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


当装饰器需要参数时,必须使用第二级封装。

Python代码

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时,一个好的方法是将它们聚集在一个易于维护的模块中。


参数检查:

Python代码

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)


缓存:

Python代码

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)



代理:

Python代码

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()


上下文提供者:

Python代码

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()


声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。