python装饰器原理梳理

        python中的装饰器和java的注解在外观上很像。python中,装饰器本质上是一个类或一个带有返回类型为函数的高阶函数。

        装饰器可以扩展一个类或函数的功能。有关装饰器的详细介绍,推荐查看文章“Python装饰器注解

        下面讲讲python中装饰器的本质,我在bilibili上找到一个讲的很好的一个视频,链接是:

【python】装饰器超详细教学,用尽毕生所学给你解释清楚,以后再也不迷茫了!_哔哩哔哩_bilibili

def dec(f):
    pass

@dec
def double(x):
    return x *2

#上面double函数上增加注解后,完全等价于下面的写法
double = dec(double)

        可以看到,装饰器本质上是一个返回类型为函数的高阶函数。当在一个普通函数上增加注解,则本质上系统会调用装饰器函数dec,参数为函数对象double,然后装饰器函数返回一个函数对象,并赋值给一个跟函数名同名的对象double。

例子1: 下面看一个实际的例子

def timeit(f):

    def wrapper(x):
        start = time.time()
        ret = f(x)
        print(time.time() - start)
        return ret

    return wrapper


@timeit
def my_func(x):
    time.sleep(1)


if __name__ == '__main__':
    my_func(1)

运行后输出

1.005021095275879

编译器运行到下面代码的时候

@timeit
def my_func(x):
    time.sleep(1)

所以其本质是运行了

my_func = timeit(my_func)

所以当调用my_func(1)时,实际上是在执行wrapper(1)。

例子二:注解上还可以增加注解

        看看下面的代码运行结果是什么

import time


def timeit(f):

    def wrapper(x):
        start = time.time()
        ret = f(x)
        print(time.time() - start)
        return ret

    return wrapper

@timeit
@timeit
def my_func(x):
    time.sleep(1)


if __name__ == '__main__':
    my_func(1)

运行后结果为:

1.0050477981567383
1.0051438808441162

编译器运行到下面代码时

@timeit
@timeit
def my_func(x):
    time.sleep(1)

实际上执行了my_func=timeit(timeit(my_func))

例子3: 装饰器有参数

        看看下面代码

import time


def timeit(k):

    def inner(f):

        def wrapper(x):
            start = time.time()
            for _ in range(k):
                ret = f(x)
            print(time.time() - start)
            return ret

        return  wrapper

    return inner

@timeit(2)
def my_func(x):
    time.sleep(1)


if __name__ == '__main__':
    my_func(1)

其中

@timeit(2)
def my_func(x):
    time.sleep(1)

本质上变成了

my_func = timeit(2)(my_func)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值