Python如何创建装饰器时保留函数元信息
问题
你写了一个装饰器作用在某个函数上,但是这个函数的重要的元信息比如名字、文档字符串、注解和参数签名都丢失了。
解决方案
任何时候你定义装饰器的时候,都应该使用 functools 库中的 @wraps 装饰器来注解底层包装函数。例如:
import timefrom functools import wrapsdef 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__’ntCounts downnt’>>> 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保留函数元信息的资料请关注好吧啦网其它相关文章!
相关文章:
1. 解决VUE项目使用Element-ui 下拉组件的验证失效问题2. 解决VUE 在IE下出现ReferenceError: Promise未定义的问题3. CSS3实例分享之多重背景的实现(Multiple backgrounds)4. Docker暴露2375端口导致服务器被攻击问题及解决方法5. uni-app结合PHP实现单用户登陆demo及解析6. 数组在java中的扩容的实例方法7. CSS3中Transition属性详解以及示例分享8. Javaweb工程运行报错HTTP Status 404解决办法9. 利用FastReport传递图片参数在报表上展示签名信息的实现方法10. jsp网页实现贪吃蛇小游戏

网公网安备