当前位置:首页>python>在python的装饰器之下,函数竟然不再是以前的函数,怎么回事?

在python的装饰器之下,函数竟然不再是以前的函数,怎么回事?

  • 2026-08-20 01:29:31
在python的装饰器之下,函数竟然不再是以前的函数,怎么回事?

一名二三线城市物联网行业程序员,卡在黄风怪吃灰中,非著名脑洞开发者。感谢您抽出时间来阅读我的文章,开心地多啃了三根草。

杂谈

卡卡正在给团队肝一份“有手就行”的公共代码,为了让队友们秒懂且能无脑调用,我直接献祭了十几年修炼的语文功底,给每个函数都写起了小作文。

代码的样子就像下面这样:

defhello():'''    这里是一个hello函数    :return: int    '''return0

如此一来,虽然为此头发掉了不少,但胜在“对队友像春天般温暖”,直接在小伙伴心里把自己写成了“史诗级文档侠”,形象瞬间两米八。

为了归档,卡卡利用每个函数的 __name__ 和 __doc__ 输出成一个html,这就变成了非常直观方便的函数手册,堪称完美。

但是在开发过程中发现需要一个通用方法去控制每个函数的输出,这难不倒卡卡,直接加上一个 装饰器,手拿把掐。

defhandler(f):definner(*args, **kwargs):return f(*args, **kwargs)return inner@handlerdefhello():'''    这里是一个hello函数    :return: int    '''return0

不过,此时发生了意外,再来看那html手册,竟然出现了纰漏:

函数名称变为了装饰器中的 inner,函数描述竟然成了 None,这不是让我掉了那么多头发写的描述都白费了吗?

原因

一个函数在被使用装饰器的情况下,它的元数据将会丢失,即 __name__ 、__doc__ 等等,取而代之的是会被装饰器中的闭包函数替代,因此如果我们如下修改,便会输出闭包函数的内容:

defhandler(f):def inner(*args, **kwargs):'''        这里是闭包        '''return f(*args, **kwargs)return inner@handlerdef hello():'''    这里是一个hello函数    :return: int    '''return0print(hello.__name__) # innerprint(hello.__doc__) # 这里是闭包

可想而知,这不是卡卡所希望看到的,我们需要以前的函数元数据来输出成文档手册。

wraps

有没有办法解决这个问题?当然有,python团队早就提供了相应的方法 @wraps

没错,这个 wraps 也是一个装饰器,它的用法如下:

from functools import wrapsdef handler(f):    @wraps(f)def inner(*args, **kwargs):'''        这里是闭包        '''return f(*args, **kwargs)return inner@handlerdef hello():'''    这里是一个hello函数    :return: int    '''return 0print(hello.__name__) # helloprint(hello.__doc__) # 这里是一个hello函数...

此时输出正是函数原来的元数据内容,完美解决这次危机。

结论

在python内部有非常多实用的内置方法,可以帮助我们解决许多奇奇怪怪的问题。

即使目前你遇到的问题没法解决,相信在未来,python团队也会慢慢升级迭代,去适配解决这些普世问题。

往期回顾:

用python解锁知识付费:我们做了一个「不翻车」的群聊系统

python做完网站就能挣钱?SEO将是你的长期饭票

做客户端软件香?还是Web端更香?应该怎么选

美国黑客攻击北京时间,为什么会引起海啸?程序员角度来解读便一目了然

奇了个怪and离了个谱,这样的xls为什么python解析不出来

最新文章

随机文章