• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

functools.wraps 装饰器

python 搞代码 4年前 (2022-01-09) 23次浏览 已收录 0个评论

wraps其实没有实际的大用处, 就是用来解决装饰器导致的原函数名指向的函数 的属性发生变化的问题;

装饰器装饰过函数func, 此时func不是指向真正的func,而是指向装饰器中的装饰过的函数

import sysdebug_log = sys.stderrdef trace(func):        if debug_log:                def callf(*args, **kwargs):                        """A wrapper function."""                        debug_log.write('Calling function: {}\n'.format(func.__name__))                        res = func(*args, **kwargs)<strong style="color:transparent">本文来源gao@daima#com搞(%代@#码网@</strong>                        debug_log.write('Return value: {}\n'.format(res))                        return res                return callf        else:                return func@tracedef square(x):        """Calculate the square of the given number."""        return x * x

这里的 square 其实指向的是 calls, 可以用help(square)或者 square.__name__ 看下。

square 被装饰后的函数其实已经是另外一个函数了(函数名等函数属性会发生改变)

如果使用wraps进行修饰

def trace(func):        if debug_log:          @functools.wraps(func)                def callf(*args, **kwargs):                        """A wrapper function."""                        debug_log.write('Calling function: {}\n'.format(func.__name__))                        res = func(*args, **kwargs)                        debug_log.write('Return value: {}\n'.format(res))                        return res                return callf        else:                return func

此时 用trace 装饰的 square 的属性就不会变化了,可以help(square) 看看

原因:我们把wraps的装饰的代码翻译如下,其等价为:

def trace(func):        if debug_log:                def _callf(*args, **kwargs):                        """A wrapper function."""                        debug_log.write('Calling function: {}\n'.format(func.__name__))                        res = func(*args, **kwargs)                        debug_log.write('Return value: {}\n'.format(res))                        return res                callf = functools.update_wrapper(_callf, wrapped = func,assigned = functools.WRAPPER_ASSIGNMENTS,updated = functools.WRAPPER_UPDATES)                return callf        else:                return func

update_wrapper做的工作很简单,就是用参数wrapped表示的函数对象(例如:square)的一些属性(如:__name__、 __doc__)覆盖参数wrapper表示的函数对象(例如:callf,这里callf只是简单地调用square函数,因此可以说callf是 square的一个wrapper function)的这些相应属性。

因此,本例中使用wraps装饰器“装饰”过callf后,callf的__doc__、__name__等属性和trace要“装饰”的函数square的这些属性完全一样。


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:functools.wraps 装饰器

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址