Python 装饰器的典型使用场景(2)

本文介绍了Python装饰器作为代理和上下文提供者的两种典型应用场景。代理装饰器用于控制函数访问权限,通过验证用户角色实现安全保护;上下文装饰器则确保函数在正确的环境中运行,并在前后执行必要的操作。

Python 装饰器的典型使用场景(2)


前一篇文章中(http://blog.youkuaiyun.com/qq_26886929/article/details/54091962),我们谈了装饰器的两方面用法,本文将讨论装饰器用作代理(Proxy)和上下文提供者(Context Provider)两个用途:


1. 代理(Proxy)装饰器

代理装饰器可被用作标记和注册函数的全局机制。例如,根据当前用户,保护对代码进行访问的安全层,可以使用一个关联着可调用对象所要求的权限的集中检测器来实现:

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

这种模式常常被用在 Python 网络框架中,来定义可发布类的安全。例如,Django 使用装饰器来提供函数访问的安全。

下面是个例子,在这个例子中当前用户被保存在一个全局变量中。当方法被调用时,装饰器会检查该用户的角色,以觉得该用户是否有访问权限:

>>> 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()
use tons of butter!
>>> user = bill
>>> these_are.waffle_recipe()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 7, in wrap
__main__.Unauthorized: I won't tell you

2. 上下文提供者(Context Provider)

上下文装饰器被用来确保函数在正确的上下文环境运行,或者确保在函数运行前和运行后执行一些代码。换言之,该装饰器进行设置或取消设置某个特定的运行环境。例如,当一条数据要在多个线程之间共享时,就需要使用锁(lock)来确保数据被保护,以防出现并发访问。锁能够像下面这样放在装饰器中:

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(): # make sure it locks the resource
    pass

上下文装饰器,通常被上下文管理器(with 语句)取代。


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值