part 1: decorator装饰器
一个装饰器是一个函数,它可以将另外一个函数作为参数输入,传入的函数将是一个新的
1 #跟普通函数没有什么区别 2 def identity(f): 3 return f 4 5 #我们使用了identity作为装饰器 6 @identify 7 def foo(): 8 return 'bar' 9 10 #相当于 11 foo = identify(foo) #返回<function foo at 0x01317C30>
上面的装饰器没有做什么特别的功能
下面看一个例子
1 _functions = {} 2 3 def register(f): 4 #全局变量 5 global _functions 6 #讲函数的名字作为字典存储起来 7 _functions[f.__name__] = f 8 return f 9 10 @register 11 def foo(): 12 return 'bar' 13 14 运行 15 >>> _functions 16 {'foo': <function foo at 0x01317BF0>} 17 >>> _functions['foo']() 18 'bar' 19 >>>
考虑一个问题,有一系列的函数需要检查权限才可以执行:
1 class Store(object): 2 def get_food(self, username, food): 3 if username != 'admin': 4 raise Exception("Not allow") 5 return self.storage.get(food) 6 7 8 def put_food(self, username, food): 9 if username != 'admin': 10 raise Exception("Not allow") 11 return self.storage.put(food) 12 13 14 #也许有人会这么想,先把检查函数写出来 15 16 def check_is_admin(username): 17 if usernmae != 'admin': 18 raise Exception("Not allow") 19 20 class Store(object): 21 def get_food(self, username, food): 22 check_is_admin(username) 23 24 return self.storage.get(food) 25 26 27 def put_food(self, username, food): 28 check_is_admin(username) 29 30 return self.storage.put(food)
这样做也行,但是我们可以用装饰器来搞定
1 def check_is_admin(f): 2 def wrapper(*args, **kwargs): 3 if kwargs.get('username') != 'admin': 4 raise Exception("Not allow") 5 return f(*args, **kwargs) 6 return wrapper 7 8 class Store(object): 9 @check_is_admin 10 def get_food(self, username, food): 11 return self.storge.get(food) 12 13 @check_is_admin 14 def put_food(self, username, food): 15 return self.storge.put(food) 16 17 18 运行 19 >>> a = Store() 20 >>> a.get_food('who','apple') 21 22 Traceback (most recent call last): 23 File "<pyshell#1>", line 1, in <module> 24 a.get_food('who','apple') 25 File "E:\新建文件夹 (3)\pro\3.py", line 4, in wrapper 26 raise Exception("Not allow") 27 Exception: Not allow 28 >>>

浙公网安备 33010602011771号