内容:
1.装饰器基本结构复习
2.装饰器注意事项
python装饰器详细内容:http://www.cnblogs.com/wyb666/p/8748102.html
1.装饰器基本结构复习
装饰器是python特有的一种特性,基本结构如下:
1 def wapper(func): 2 def inner(*args, **kwargs): 3 # 代码 4 func() 5 # 代码 6 return inner 7 8 或者这样: 9 10 def wapper(func): 11 def inner(*args, **kwargs): 12 # 代码 13 return func() 14 return inner
2.装饰器注意事项
像上面那样的装饰器,在使用的时候会改变函数的一些基本信息(比如下面的__name__):
1 import time 2 3 def timmer(func): 4 def warpper(*args, **kwargs): 5 start_time = time.time() 6 func() 7 stop_time = time.time() 8 print("The func run time is %s" % (stop_time-start_time)) 9 return warpper 10 11 12 @timmer 13 def f1(): 14 time.sleep(3) 15 print(f1.__name__) # warpper 16 17 f1()
我们可以使用如下的方法再对上述的warpper加一个装饰器,将名字转换回来
1 import time 2 import functools 3 4 def timmer(func): 5 @functools.wraps(func) # 帮助我们设置函数的元信息还等于原来的函数名 6 def warpper(*args, **kwargs): 7 start_time = time.time() 8 func() 9 stop_time = time.time() 10 print("The func run time is %s" % (stop_time-start_time)) 11 return warpper 12 13 14 @timmer 15 def f1(): 16 time.sleep(3) 17 print(f1.__name__) # f1 18 19 f1()
这样做可以保留原函数的一些基本信息
functools.wraps()相当于保留元信息,如果不加这个装饰器,那么你打印f1的__name__它就是warpper,因为加了装饰器,效果等同于warpper=warpper(f1()),
如果在装饰器中加了functools这个装饰器,那么相当于给__name__重新赋值,warpper.__name__ = func.__name_,让其函数的名字得以保留
3.flask框架的视图函数加装饰器
给flask框架的视图函数加装饰器有两种写法:
(1)使用endpoint表明函数名
1 def wapper(func): 2 def inner(*args,**kwargs): 3 user = session.get('user_info') 4 if not user: 5 return redirect('/login') 6 return func(*args,**kwargs) 7 return inner 8 9 10 @app.route('/detail/<int:nid>',methods=['GET'],endpoint='n1') 11 @wapper 12 def detail(nid): 13 print(nid) 14 return render_template('hello.html')
注:
如果给一个视图函数增加装饰器,应该加在app.route下面,这样的效果就是,装饰器将下面的所有内容包裹,然后路由对应到这大的包裹中来。
需要注意endpoint要注明,如果不注明endpoint则默认用函数名来定义,此时所有的函数名都叫inner了,所以需要注明endpoint,只是为了区分。
(2)使用functools设置函数的元信息还等于原来的函数名
1 import functools 2 3 def wapper(func): 4 @functools.wraps(func) 5 def inner(*args,**kwargs): 6 return func(*args,**kwargs) 7 return inner 8 9 @app.route('/login', method=['GET', 'POST']) 10 @wapper 11 def detail(): 12 pass 13 14 print(detail.__name__) # detail