欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  后端开发

Python装饰器

程序员文章站 2022-04-21 17:13:33
...
编写自定义装饰器有许多方法,但最简单和最容易理解的方法是编写一个函数,返回封装原始函数调用的一个子函数。

通用的模式如下。

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