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

 更新时间:2020年08月07日 16:00:04   作者:D  
这篇文章主要介绍了Python如何创建装饰器时保留函数元信息,文中讲解非常细致,帮助大家更好的理解和学习,感兴趣的朋友可以了解下

问题

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

解决方案

任何时候你定义装饰器的时候,都应该使用 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保留函数元信息的资料请关注脚本之家其它相关文章!

相关文章

  • pandas使用之宽表变窄表的实现

    pandas使用之宽表变窄表的实现

    这篇文章主要介绍了pandas使用之宽表变窄表的实现方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-04-04
  • pyv8学习python和javascript变量进行交互

    pyv8学习python和javascript变量进行交互

    这篇文章主要介绍了pyv8学习python和javascript变量进行交互,python取得javascript里面的值、javascript取得python里面的值、python和javascript里面的函数交互
    2013-12-12
  • Python异常处理之try...except语句

    Python异常处理之try...except语句

    Python异常处理是Python中重要的一部分,为了保证程序的稳定性和可靠性,我们需要使用异常处理来及时捕获,并以优雅的方式来处理这些异常,本教程将介绍如何处理 Python中的异常,需要的朋友可以参考下
    2023-06-06
  • 解决Pycharm 导入其他文件夹源码的2种方法

    解决Pycharm 导入其他文件夹源码的2种方法

    今天小编就为大家分享一篇解决Pycharm 导入其他文件夹源码的2种方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-02-02
  • 用Python编写一个简单的CS架构后门的方法

    用Python编写一个简单的CS架构后门的方法

    今天小编就为大家分享一篇关于用Python编写一个简单的CS架构后门的方法,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-11-11
  • tensorflow 查看梯度方式

    tensorflow 查看梯度方式

    今天小编就为大家分享一篇tensorflow 查看梯度方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-02-02
  • Python网络编程基于多线程实现多用户全双工聊天功能示例

    Python网络编程基于多线程实现多用户全双工聊天功能示例

    这篇文章主要介绍了Python网络编程基于多线程实现多用户全双工聊天功能,结合实例形式分析了Python网络编程中使用多线程进行多用户异步通信的原理与相关实现技巧,需要的朋友可以参考下
    2018-04-04
  • Python 中下划线的几种用法(_、_xx、xx_、__xx、__xx__)

    Python 中下划线的几种用法(_、_xx、xx_、__xx、__xx__)

    本文主要介绍了Python 中下划线的几种用法(_、_xx、xx_、__xx、__xx__),详细的介绍了这几种下划线的用处,具有一定的参考价值,感兴趣的可以了解一下
    2023-09-09
  • JetBrains PyCharm(Community版本)的下载、安装和初步使用图文教程详解

    JetBrains PyCharm(Community版本)的下载、安装和初步使用图文教程详解

    这篇文章主要介绍了JetBrains PyCharm(Community版本)的下载、安装和初步使用教程,本文图文并茂给大家介绍的非常详细,对大家的学习和工作具有一定的参考借鉴价值 ,需要的朋友可以参考下
    2020-03-03
  • Python 性能优化技巧总结

    Python 性能优化技巧总结

    代码优化能够让程序运行更快,它是在不改变程序运行结果的情况下使得程序的运行效率更高,根据 80/20 原则,实现程序的重构、优化、扩展以及文档相关的事情通常需要消耗 80% 的工作量。优化通常包含两方面的内容:减小代码的体积,提高代码的运行效率。
    2016-11-11

最新评论