Python如何创建装饰器时保留函数元信息

 更新时间:2020年08月07日 16:00:04   作者:D  
这篇文章主要介绍了Python如何创建装饰器时保留函数元信息,文中讲解非常细致,帮助大家更好的理解和学习,感兴趣的朋友可以了解下
(福利推荐:【腾讯云】服务器最新限时优惠活动,云服务器1核2G仅99元/年、2核4G仅768元/3年,立即抢购>>>:9i0i.cn/qcloud

(福利推荐:你还在原价购买阿里云服务器?现在阿里云0.8折限时抢购活动来啦!4核8G企业云服务器仅2998元/3年,立即抢购>>>:9i0i.cn/aliyun

问题

你写了一个装饰器作用在某个函数上,但是这个函数的重要的元信息比如名字、文档字符串、注解和参数签名都丢失了。

解决方案

任何时候你定义装饰器的时候,都应该使用 functools 库中的 @wraps 装饰器来注解底层包装函数。例如:

import time
from functools import wraps
def timethis(func):
  '''
  Decorator that reports the execution time.
  '''
  @wraps(func)
  def wrapper(*args, **kwargs):
    start = time.time()
    result = func(*args, **kwargs)
    end = time.time()
    print(func.__name__, end-start)
    return result
  return wrapper

下面我们使用这个被包装后的函数并检查它的元信息:

>>> @timethis
... def countdown(n):
...   '''
...   Counts down
...   '''
...   while n > 0:
...     n -= 1
...
>>> countdown(100000)
countdown 0.008917808532714844
>>> countdown.__name__
'countdown'
>>> countdown.__doc__
'\n\tCounts down\n\t'
>>> countdown.__annotations__
{'n': <class 'int'>}
>>>

讨论

在编写装饰器的时候复制元信息是一个非常重要的部分。如果你忘记了使用 @wraps , 那么你会发现被装饰函数丢失了所有有用的信息。比如如果忽略 @wraps 后的效果是下面这样的:

>>> countdown.__name__
'wrapper'
>>> countdown.__doc__
>>> countdown.__annotations__
{}
>>>

@wraps 有一个重要特征是它能让你通过属性 __wrapped__ 直接访问被包装函数。例如:

>>> countdown.__wrapped__(100000)
>>>

__wrapped__ 属性还能让被装饰函数正确暴露底层的参数签名信息。例如:

>>> from inspect import signature
>>> print(signature(countdown))
(n:int)
>>>

一个很普遍的问题是怎样让装饰器去直接复制原始函数的参数签名信息, 如果想自己手动实现的话需要做大量的工作,最好就简单的使用 @wraps 装饰器。 通过底层的 __wrapped__ 属性访问到函数签名信息。

以上就是Python如何创建装饰器时保留函数元信息的详细内容,更多关于Python保留函数元信息的资料请关注程序员之家其它相关文章!

相关文章

  • Python使用Pillow进行图像处理

    Python使用Pillow进行图像处理

    这篇文章介绍了Python使用Pillow进行图像处理的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-06-06
  • Pycharm配置导入torch报错Traceback的问题及解决

    Pycharm配置导入torch报错Traceback的问题及解决

    这篇文章主要介绍了Pycharm配置导入torch报错Traceback的问题及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-12-12
  • pandas改变df列的顺序的方法实现

    pandas改变df列的顺序的方法实现

    本文主要介绍了pandas改变df列的顺序的方法实现,主要使用 Pandas 中的 reindex() 方法,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧
    2024-03-03
  • python?教程实现?turtle海龟绘图

    python?教程实现?turtle海龟绘图

    这篇文章主要介绍了python?教程实现?turtle绘制海龟绘图,文章基于python的相关资料展开turtle绘制海龟绘图的详细内容,需要的小伙伴可以参考一下
    2022-05-05
  • Python利用watchdog模块监控文件变化

    Python利用watchdog模块监控文件变化

    这篇文章主要为大家介绍一个Python中的模块:watchdog模块,它可以实现监控文件的变化。文中通过示例详细介绍了watchdog模块的使用,需要的可以参考一下
    2022-06-06
  • libreoffice python 操作word及excel文档的方法

    libreoffice python 操作word及excel文档的方法

    这篇文章主要介绍了libreoffice python 操作word及excel文档的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-07-07
  • python在每个字符后添加空格的实例

    python在每个字符后添加空格的实例

    今天小编就为大家分享一篇python在每个字符后添加空格的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-05-05
  • Python创建一个空的dataframe,并循环赋值的方法

    Python创建一个空的dataframe,并循环赋值的方法

    今天小编就为大家分享一篇Python创建一个空的dataframe,并循环赋值的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-11-11
  • Python3之字符串比较_重写cmp函数方式

    Python3之字符串比较_重写cmp函数方式

    这篇文章主要介绍了Python3之字符串比较_重写cmp函数方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-02-02
  • python或C++读取指定文件夹下的所有图片

    python或C++读取指定文件夹下的所有图片

    这篇文章主要为大家详细介绍了python或C++读取指定文件夹下的所有图片,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-08-08

最新评论

?


http://www.vxiaotou.com