编写装饰器并保存函数的元数据,代码简洁之道
admin
2023-07-19 23:02:04
0次

    软件开发中的重要一条真理就是“不要重复自己的工作”。通常当我们需要创建高度重复的代码时,都可以寻找到一个更加优雅的解决方案。

1    给函数添加一个包装,让它做一点额外的工作

    当我们需要让一个函数拥有计时统计、打印日志的功能时,往往选择的方案就是直接在函数体中增加需要的代码。这在只有一两个函数的时候还可以接受,但是如果需要让一个项目中的所有函数都具有这样的功能时,就会变得十分繁琐。

    这时候,就需要我们使用“装饰器”了。示例如下:

from functools import wraps
import time

def logit(func):
    '''
    使用装饰器来打印函数调用信息
    '''

    @wraps(func)
    def wrapper(*args, **kwargs):
        print('start func {}'.format(func.__name__),
              time.strftime('at %Y %m %d %H:%M:%S', time.localtime()))
        result = func(*args, **kwargs)
        print('finish func {}'.format(func.__name__),
              time.strftime('at %Y %m %d %H:%M:%S', time.localtime()))
        return result
    return wrapper

    下面是使用演示:

>>> @logit
def countdown(n):
    while(n > 0):
        n -= 1
>>> countdown(10000000)
start func countdown at 2018 09 16 16:45:23
finish func countdown at 2018 09 16 16:45:24

    只需要在函数定义时为它增加一个装饰器(@logit),这个函数就能告诉我们它开始运行的时间以及结束运行的时间!

    装饰器其实就是一个函数,它可以接受一个函数作为输入并返回一个新的函数作为输出。

    装饰器内部的代码一般会涉及创建一个新的函数,利用*args和**kwargs可以接收任意的参数。在这个函数内部,我们调用原来的输入函数(即被包装的那个函数,它是装饰器的输入参数)并返回它的结果。此时,这个新创建的wrapper函数就会作为装饰器的结果返回,取代了原本的函数。

    需要强调的一点是,装饰器一般来说不会修改调用的签名,也不会修改被包装函数返回的结果。这里使用了*args和**kwargs来确保可以接受任何形式的输入参数。装饰器的返回值几乎总是同调用func(*args,**kwargs)的结果一致,这里的func就是那个未被包装过的原始函数。

2    那装饰器函数中的装饰器@wraps有什么作用

    装饰器@wraps可以用来保存底层的元数据,比如函数名、文档字符串、函数注解以及调用签名。

    如果没有使用该装饰器,获取上一个例子中countdown函数的元数据就会看起来像这样:

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

    @wraps的另一个重要特性就是可以通过__wrapped__属性来访问那个被包装的函数,而该属性同时也可以使得装饰器函数可以合适的将底层被包装的函数的签名暴露出来:

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

编写装饰器并保存函数的元数据,代码简洁之道

相关内容

热门资讯

空调连续工作多久需要停机休息 空调连续工作的时间取决于多个因素,包括空调的型号、功率、使用环境和维护情况等。一般来说,空调可以连续...
空调哪个符号是除湿的 空调除湿功能通常用一个水滴形状的符号表示。不同品牌和型号的空调遥控器可能会有所差异,但一般来说,除湿...
格力空调多长时间加一次氟利昂 1、一般情况下,空调对氟利昂的使用量是非常小的,所以在空调使用了四年左右的时候再考虑加也没问题。2、...
空调用多长时间需要加氟一次 一般情况下是五年。当出现以下这几种情况时,空调才需要加氟。1、空调的室内机和室外机各有两个接口,当接...
格调生活·C标思享荟:卡萨帝在... 9月12日的郑州龙湖金融岛,夜风轻拂,灯光璀璨。“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑...
品牌价值破千亿、高端份额持续领... 9月12日,“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑州站”在郑州龙湖金融岛举办。2026...
空调主板坏了修800还是换新的 空调主板坏了是修还是换新,需要考虑多个因素,以下是一些建议:1. 维修成本:如果维修费用较低,比如 ...
空调开多久需要休息多长时间 问题:空调开多久需要休息多长时间回答:1、在使用空调的过程中,一般空调开7~8个小时左右需要休息2~...
中央空调多长时间清洗一次 1、一般空调开机前清洗一次即可,空调开机中间时段再清洗一次,空调关机时清洗一次,这样比较合理。2、空...
中央空调氟利昂多久加一次 看空调制热和制冷程度,很多人的观点认为氟利昂必须一年放一次,其实这个观点是错误的,理解上面有点偏差,...