【python】详解装饰器@的使用:性能测试、装饰器参数、调用顺序、内置装饰器

python中使用’@’ 作为函数的修饰符,可以在模块或者类的定义层内对函数进行修饰,出现在函数定义的前一行,不允许和函数定义在同一行。一个修饰符就是一个函数,它将被修饰的函数作为参数,并返回修饰后的同名函数或其他可调用的东西。

装饰模式有很多经典的使用场景,例如插入日志、性能测试、事务处理等等,有了装饰器,就可以提取大量函数中与本身功能无关的类似代码,从而达到代码重用的目的。

1、通过装饰器重用功能对多对象进行性能测试:
我们可以直接把计时逻辑方法my_func内部,但是这样的话,如果要给另一个函数计时,就需要重复计时的逻辑。所以比较好的做法是把计时逻辑放到另一个函数中(timecount),如下:

输出结果:

但是,上面的做法也有一个问题,就是所有的my_func调用处都要改为timecount(my_func)。下面,做一些改动,来避免计时功能对my_func函数调用代码的影响:

输出结果:

经过了上面的改动后,一个比较完整的装饰器(timecount)就实现了,装饰器没有影响原来的函数,以及函数调用的代码。例子中值得注意的地方是,Python中一切都是对象,函数也是,所以代码中改变了”my_func”对应的函数对象。

2、装饰器语法糖,在Python中,可以使用”@”语法糖来精简装饰器的代码

  • 初始计时使用@语法糖表达:

输出结果:

  • 加入wrapper后的表达:

输出结果:

使用了”@”语法糖后,我们就不需要额外代码来给”my_func”重新赋值了,雅思听力标准其实@timecount的本质就是my_func=timecount(my_func),当认清了这一点后,后面看带参数的装饰器就简单了。

3、被装饰的函数带参数

对于被装饰函数需要支持参数的情况,我们只要使装饰器的内嵌函数支持同样的表达式即可。

输出结果:

这里还有一个问题,如果多个函数拥有不同的参数形式,怎么共用同样的装饰器?在Python中,函数可以支持(*args, **kwargs)可变参数,所以装饰器可以通过可变参数形式来实现内嵌函数的签名

输出结果:

4、带参数的装饰器

  • 如果装饰器本身需要支持参数,那么装饰器就需要多一层的内嵌函数

输出结果:

5、装饰器调用顺序

  • 装饰器是可以叠加使用的,那么这是就涉及到装饰器调用顺序了。对于Python中的”@”语法糖,英国留学费用装饰器的调用顺序与使用 @ 语法糖声明的顺序相反

输出结果:

Python内置装饰器

在Python中有三个内置的装饰器,都是跟class相关的:staticmethod、classmethod 和property。

  • staticmethod 是类静态方法,其跟成员方法的区别是没有 self 参数,并且可以在类不进行实例化的情况下调用

输出结果:

    • classmethod 与成员方法的区别在于所接收的第一个参数不是 self (类实例的指针),而是cls(当前类的具体类型)
    • property 是属性的意思,表示可以通过通过类实例直接访问的信息 

猜你喜欢

转载自www.cnblogs.com/zhaolide/p/10031956.html