问题

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

很多人学习python,不知道从何学起。
很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手。
很多已经做案例的人,却不知道如何去学习更加高深的知识。
那么针对这三类人,我给大家提供一个好的学习平台,免费领取视频教程,电子书籍,以及课程的源代码!
QQ群:101677771

解决方案

任何时候你定义装饰器的时候,都应该使用 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 resultreturn 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博客其它相关文章!

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

  1. python 运行时间 装饰器_python 装饰器统计某个函数的运行时间

    import datetime def count_time(func): def int_time(*args, **kwargs): start_time = datetime.datetime. ...

  2. python装饰器函数-python装饰器1:函数装饰器详解

    先混个眼熟 谁可以作为装饰器(可以将谁编写成装饰器): 函数 方法 实现了__call__的可调用类 装饰器可以去装饰谁(谁可以被装饰): 函数 方法 类 基础:函数装饰器的表现方式 假如你已经定义了 ...

  3. python高阶函数闭包装饰器_5.初识python装饰器 高阶函数+闭包+函数嵌套=装饰器...

    一.什么是装饰器? 实际上装饰器就是个函数,这个函数可以为其他函数提供附加的功能. 装饰器在给其他函数添加功能时,不会修改原函数的源代码,不会修改原函数的调用方式. 高阶函数+函数嵌套+闭包 = 装饰 ...

  4. python装饰器带参数函数二阶导数公式_一文搞定Python装饰器,看完面试不再慌

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是Python专题的第12篇文章,我们来看看Python装饰器. 一段囧事 差不多五年前面试的时候,我就领教过它的重要性.那时候我Pyt ...

  5. python 开闭原则_Python 装饰器@,对函数进行功能扩展操作示例【开闭原则】

    本文实例讲述了Python 装饰器@,对函数进行功能扩展操作.分享给大家供大家参考,具体如下: 装饰器可以对原函数进行功能扩展,但还不需要修改原函数的内容(开闭原则),也不需要修改原函数的调用. de ...

  6. 初学者python笔记(装饰器、高阶函数、闭包)

    一个函数被定义完成后,甚至程序发布后,后期可能需要添加某些功能,但是我们不可能每次都去修改原函数的代码,这时候装饰器就可以上场了,本篇文章将会用一个个可实现的代码,由浅入深.循序渐进得阐述装饰器的强大 ...

  7. python装饰器带参数函数_python带参数装饰器的两种写法

    python带参数装饰器的两种写法 前言 最近在实现一个装饰器的过程中发现了一个很有意思的地方,在博客里面分享出来 不同的写法 三层函数嵌套,实现了可传参数的一个装饰器. import logging ...

  8. python装饰器模式带参数_Python进阶(七)----带参数的装饰器,多个装饰器修饰同一个函数和递归简单案例(斐波那契数列)...

    Python进阶(七)----带参数的装饰器,多个装饰器修饰同一个函数和递归简单案例(斐波那契数列) 一丶带参数的装饰器 def wrapper_out(pt): def wrapper(func): ...

  9. python万能装饰器实现计算函数的调用次数和执行时间

    直接上代码 # python万能装饰器实现计算函数的调用次数和执行时间 import timedef set_fun(func):num = 0 # 初始化次数def call_fun(*args, ...

最新文章

  1. Android - Android Studio 解决访问被墙的问题
  2. python算法书籍-你也能看得懂的Python算法书
  3. centos6.5环境wget报错Unable to establish SSL connection
  4. 中国人工智能学会通讯——机器人组件技术在智能制造系统中的应用
  5. ckks方案优化最好的_站群如何优化才能提高SEO效果?站群优化方案有哪些?
  6. 操作符和表达式的问题总结
  7. java判断是否安装了pdf_Java检查PDF文件是否损坏
  8. java扫雷随机地雷_原创扫雷(未添加随机分布地雷),想看就进来看下吧
  9. 飞秋文件传输模拟实现代码
  10. P1002 [NOIP2002 普及组] 过河卒(python3实现)
  11. 《数学与生活》的3本书籍
  12. java arraylist 构造_深入理解java集合框架之---------Arraylist集合 -----构造函数
  13. 下载软件的临时文件思路和实现
  14. 软件工程java向量相似度计算_向量的相似度计算常用方法9个
  15. Spring -- spring 和 hibernate 整合
  16. 机器学习算法——GBDT
  17. java2048朝代版代码_2048朝代版完整版
  18. 安庆集团-冲刺日志(第二天)
  19. 云服务器BCc怎么创建php环境,百度智能云服务器BCC如何升级wordpress的php环境
  20. 【模型】【课程笔记】01+02+03 金融风险管理导论

热门文章

  1. 景观分析工具:arcgis中patch analysis模块
  2. android中的websocket 应用
  3. Hangfire入门(任务调度)
  4. Tomcat配置多个Service,多个同名的应用运行在一个tomcat下
  5. 忘记glassfish密码,那就重置密码呗
  6. vSphere系列二 ---VMware vSphere Client安装
  7. 如何修改SQL Server 2000身份验证模式和系统管理员
  8. StreamWriter、StreamReader 写读文件的两种方法
  9. 福昕高级PDF编辑器
  10. ES6 系列之 WeakMap的使用示例