Python装饰器之一
装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。
简单的设计了一个验证权限的装饰器,设计如下
# -*- 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是基于位置的参数还是基于关键字的参数,而是只需要在字典中查询。
相关推荐
夜斗不是神 2020-11-17
huavhuahua 2020-11-20
Yasin 2020-11-16
xiaoseyihe 2020-11-16
千锋 2020-11-15
diyanpython 2020-11-12
chunjiekid 2020-11-10
wordmhg 2020-11-06
YENCSDN 2020-11-17
lsjweiyi 2020-11-17
houmenghu 2020-11-17
Erick 2020-11-17
HeyShHeyou 2020-11-17
以梦为马不负韶华 2020-10-20
lhtzbj 2020-11-17
pythonjw 2020-11-17
dingwun 2020-11-16
lhxxhl 2020-11-16