Python @functools.wraps 的作用
1:装饰器是干什么用的?
为了对一个函数在运行期的功能的拓展
2:装饰器加上之后产生的问题:
解释器认为函数本身发生了改变,其函数本身的属性改变了,在某些情况下——比如测试时——会导致一些问题
Python 通过 functool.wraps
为我们解决了这个问题:在编写装饰器时,在实现前加入 @functools.wraps(func)
可以保证装饰器不会对被装饰函数造成影响。
3:Flask 官方示例:
from functools import wraps
from flask import g, request, redirect, url_for
def login_required(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if g.user is None:
return redirect(url_for('login', next=request.url))
return f(*args, **kwargs)
return decorated_function
@app.route('/secret_page')
@login_required
def secret_page():
pass
4:详解
当装饰器装饰一个函数时,实际上就是将被装饰的函数作为一个参数传入装饰器函数,返回一个闭包,而闭包内部调用这个函数,再另外多做一些事情。然后再由我们的函数名字去接收那个返回值的闭包的引用,达到了我们装饰的目的,所以此时,我们的函数的__name__等属性其实已经改变,变成了我们闭包的私有属性。
functools.wraps()这个函数,作为一个装饰器去装饰闭包,并且给这个装饰器传入一个参数,这个参数是闭包外的装饰器装饰的那个外部的被装饰函数,此时,外部我们的自定义的函数的私有属性如__name__、__doc__等还是为我们自定义的函数本身的私有属性,而不会变成闭包的私有属性。
5:反正记住写装饰器的时候,最好是加上@wraps(f),这样可以在扩展函数功能的同时,保留原有函数的各种属性。
还没有评论,来说两句吧...