聊聊Python中的装饰器

Python装饰器是什么?

在很多程序框架中曾经使用过 @route、@app、@time等这种格式的语法,有些用在了定义视图的函数上,类似一种拦截器用来控制当前视图的访问权限。

装饰器(decorator)是干嘛的?对于受到封装的原函数来说,装饰器能够在那个函数执行前或者执行后分别运行一些代码,使得可以再装饰器里面访问并修改原函数的参数以及返回值,以实现约束定义、调试程序、注册函数等目标。装饰器一般返回一个包装器(wrapper),而functools.wraps就是装饰包装器的装饰器。

定义一个Python的装饰器

我们定义一个计算Python程序运行时间的装饰器,在定义一个需要运行的韩式,代码如下:

import time
import functools


def t(fun):
    '''定义一个程序运行时间计算函数'''
    @functools.wraps(fun)
    def wrapper(*args, **kwargs):
        start = time.time()  # 起始时间
        fun(*args, **kwargs)  # 要执行的函数
        end = time.time()  # 结束时间
        print(fun.__name__, '程序运行时间:{:.2f}ms'.format((end - start) * 1000))
    return wrapper


@t
def myfunc(x, y):
    '''打印从x到y的数值'''
    for i in range(x, y):
        print(i)

myfunc(0, 9)

运行结果:

    0
    1
    2
    3
    4
    5
    6
    7
    8
    myfunc 程序运行时间:0.03ms
    这样的话,我们就可以在不破坏原函数代码的情况下为函数添加了计算当前函数运行时间的功能。

定义一个可以传参的装饰器

如果我们的装饰器需要传入参数该怎么写呢?只需要在 wrapper 外加一层包装即可。代码如下:

import time
import functools


def t(str):
    '''定义一个程序运行时间计算函数'''
    def decorator(fun):
        @functools.wraps(fun)
        def wrapper(*args, **kwargs):
            start = time.time()  # 起始时间
            fun(*args, **kwargs)  # 要执行的函数
            end = time.time()  # 结束时间
            print('传入的字符串是:', str)
            print(fun.__name__, '程序运行时间:{:.2f}ms'.format((end - start) * 1000))
        return wrapper
    return decorator


@t('hello world')
def myfunc(x, y):
    '''打印从x到y的数值'''
    for i in range(x, y):
        print(i)


myfunc(0, 9)

运行结果:

    0
    1
    2
    3
    4
    5
    6
    7
    8
    传入的字符串是: hello world
    myfunc 程序运行时间:0.11ms
    functools.wraps是什么?

functools.wraps 是为了保留原函数的属性不被装饰器破坏,这个时候就可以使用 functools.wraps 。functools这个库里有很多关于函数的功能模块,后续我们在继续研究。

上边是两个装饰器常用的经典模版,可以按需求修改成自己的装饰器.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

这里不提提纳里

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值