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 >>>

 

posted @ 2014-10-13 20:18  pwn_pjy  阅读(171)  评论(0)    收藏  举报