python装饰器注意事项

内容:

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
原文地址:https://www.cnblogs.com/wyb666/p/9571455.html