首页 > 技术文章 > Python 进阶系列(二)

studyontheway 2017-07-28 20:40 原文

Python 装饰器常见用法

装饰器与spring 中的AOP类似 通过装饰器可以实现面向切面的注入

  • 一:缓存 (用python实现缓存)

把一些经常操作的数据,对象放入缓存,同一个对象不重复缓存,用到的是装饰器实现的 具体代码如下:


#-*- coding:utf-8 -*-
import itertools
import pickle
import hashlib
import time
cache = {}
def is_obsolete(entry,duration):
    return time.time() - entry['time'] > duration
def compute_key(function,args,kw):
    key = pickle.dumps((str(function),args,kw))
    return hashlib.sha1(key).hexdigest()
def memoize(duration=10):
    print(1)
    def __memoize(function):
        print(function.__name__)     ##输出 complex_stuff
        def __memoize(*args,**kw):
            print(args)      ##1 输出(3, 2) 2 输出  (4, 2)
            key = compute_key(function,args,kw)
            print("缓存中的内容",cache)   ##输出 缓存中的内容 {'0ef5bffbcd14911cc9e62b5d03e6b6969c60a1bc': {'time': 1501232525.6945438, 'value': 5}}
            # 缓存中的内容 {'0ef5bffbcd14911cc9e62b5d03e6b6969c60a1bc': {'time': 1501232525.6945438, 'value': 5}}
            if (key in cache and not is_obsolete(cache[key],duration)):
                print("已经缓存")  #输出一次已经缓存
                return cache[key]['value']
            result = function(*args,**kw)
            print("开始缓存数据",result)
            cache[key] = {'value':result,'time':time.time()}
            return result
        return __memoize
    return __memoize
@memoize()
def complex_stuff(a,b):
    return a+b
complex_stuff(3,2)

complex_stuff(3,2)

complex_stuff(4,2)

print("最后缓存内容有",cache)
#输出 最后缓存内容有 {'0ef5bffbcd14911cc9e62b5d03e6b6969c60a1bc': {'time': 1501232525.6945438, 'value': 5}, '0810bc870924200225714d46045fd3286ba11304': {'time': 1501232525.6945438, 'value': 6}}

  • 二 代理

    代理装饰器使用一个全局机制来标记注册函数,一个根据当前用户保护代码访问的安全层可以使用一个集中的检查器和相关的可调用对象要求的权限来实现
#-*- coding:utf-8 -*-
__author__ = 'Administrator'
class User(object):
    def __init__(self,roles):
        self.roles = roles
class Unathorized(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 Unathorized("不能使用代理")
            return function(*args,**kw)
        return __protect
    return _protect
tarek = User(('admin','user'))
bill = User(('user',))
class Myserets(object):
    @protect('admin')   #只有当user 有 admin 权限才能使用
    def waffle_recipe(self):
        print("可以使用")
these_are = Myserets()
user = tarek   ## 输出可以使用代理
these_are.waffle_recipe()
user = bill    ###抛出异常
these_are.waffle_recipe()

  • 三 上下文锁

上下文装饰器用来确保函数可以运行在正确的上下文中,或者在执行之前设置成特定的执行环境,例如当一个数据必须和其他线程共享时,就必须使用一个锁来确保它在多重访问得到保护。

#-*- coding:utf-8 -*-
__author__ = 'Administrator'
from threading import RLock
lock = RLock()
def synchronized(function):
    print(function.__name__)
    def _synchronized(*args,**kw):
        print(args)
        lock.acquire()
        print("锁住了")
        try:
            return function(*args,**kw)
        finally:
            lock.release()
    return _synchronized()
@synchronized
def thread_safe():   ##确保资源被锁住了
    print("locak")
    pass
thread_safe()

推荐阅读