Python装饰器之一

装饰器本质上是一个Python函数,它可让其余函数在不须要作任何代码变更的前提下增长额外功能,装饰器的返回值也是一个函数对象。它常常用于有切面需求的场景,好比:插入日志、性能测试、事务处理、缓存、权限校验等场景。装饰器是解决这类问题的绝佳设计,有了装饰器,咱们就能够抽离出大量与函数功能自己无关的雷同代码并继续重用。缓存

简单的设计了一个验证权限的装饰器,设计以下app

# -*- coding:utf-8 -*-

def check_is_admin(func):
    def wrapper(*args,**kwargs):
        if kwargs.get('username') != 'admin':
            raise Exception('This user is not allowed to get food')
        return func(*args,**kwargs)
    return wrapper

class Store(object):

    @check_is_admin
    def get_food(self,username,food):
        return self.get(food)

    @check_is_admin
    def put_food(self, username, food):
        return self.put(food)

    def get(self,food):
        return food

    def put(self,food):
        return food

if __name__ == '__main__':
    s = Store()
    s.get_food(**{'username':'admin1'},**{'food':'apple'})

到目前为止,咱们的示例中老是假设装饰器有一个名为username的关键字参数传入,可是实际状况并不是如此,因此咱们设计了一个更智能的装饰器,代码以下:函数

# -*- coding:utf-8 -*-
import functools,inspect

def check_is_admin(func):
    @functools.wraps(func)

    def wrapper(*args,**kwargs):
        func_args = inspect.getcallargs(func,*args,**kwargs)

        if func_args.get('username') != 'admin':
            raise Exception('This user is not allowed to get food')
        return func(*args,**kwargs)
    return wrapper

class Store(object):

    @check_is_admin
    def get_food(self,username,food):
        return self.get(food)

    @check_is_admin
    def put_food(self, username, food):
        return self.put(food)

    def get(self,food):
        return food

    def put(self,food):
        return food

if __name__ == '__main__':
    s = Store()
    food = s.get_food(**{'username': 'admin'}, food='apple')
    print(food)

这里咱们引入了functools,inspect模块。inspect.getcallargs承担了主要工做,它返回一个将参数名字和值做为键值对的字典{'username':'admin','food':'apple'},这就意味着装饰器没必要检查参数username是基于位置的参数仍是基于关键字的参数,而是只须要在字典中查询。性能

相关文章
相关标签/搜索