Python装饰器探秘

Linux编程

点击右侧关注,免费入门到精通!

一、什么是装饰器

知乎某大佬如是说:内裤可以用来遮羞,但是到了冬天它没法为我们防风御寒,聪明的人们发明了长裤,有了长裤后宝宝再也不冷了,装饰器就像我们这里说的长裤,在不影响内裤作用的前提下,给我们的身子提供了保暖的功效。

装饰器本质上是Python函数,可以为已存在的对象添加额外的功能,同时装饰器还可以抽离出与函数无关的重用代码。具体应用场景如:插入日志、性能测试、事务处理、缓存、权限校验等。

换言之

装饰器不能影响原函数的功能,装饰器是独立出来的函数。谁调用它,谁就可以使用它的功能。

二、举个栗子

add的功能是计算x和y的值,我们称作功能函数。

logger的作业是在执行add函数的同时再打印了其他的信息,这部分的作为add的功能增强,我们称为装饰。

在logger里我们可以加入其他类似的功能函数,也能包装它,可以进行复用。

1.引子

2.提取参数

x,y的参数都放在logger函数内部了,影响函数的灵活性,此处我们可以提取出来。

3.柯里化

懵逼ing

以下为个人理解,左边为非柯里化函数,右边是柯里化函数。

柯里化函数

前面说过柯里化的定义,本来可以一次传入两个参数,柯里化之后。只需要传入一个函数了。。

左边传入add 和 两个参数。

右边的logger(add)是一个函数,只需要传入两个参数。logger(add)是个整体,结合成一个函数。当然这样写,我们看函数主题的部分也是不一样的。

函数的基础中说过,函数的传参必须和函数参数的定义一致。重点分析右边函数(柯里化)。

参数部分:参数传入的方式,logger函数需要传入个fn,fu的返回值是wrapper函数,wrapper函数的参数是(*args,**kwargs)所以此次就需要分两次传入参数。

第一次传入fn,再次传入wrapper函数需要的参数。所以就出现了最下边的调用方式。

print(logger(add)(5,y=50))。

返回值部分:右侧的logger函数是个嵌套函数,logger的返回值是wrapper,内层的wrapper函数返回值是x,x = fn(*args,**kwargs)。fn函数是最后调用时候传入的add函数。

懵逼 X 2。。。。

效果如下:

继续懵逼的话就这样用吧。。。用多了就悟道了。。

4.装饰器语法糖

三、复杂的栗子

再次翻译

四、带参装饰器

1. 文档字符串

我们约定,在python函数的第一行需要对函数进行说明,使用三引号表示。

如果是英文说明,惯例首字母大写,第一行写概述,空一行,第三行写详细描述。

如果函数中有文档字符串,默认会放在函数的doc属性中,可以直接访问。

2. 前面装饰器的副作用

前面装饰器基本上已经可以完成对函数进行加强的功能了,但是还有些瑕疵。比如原来函数的原属性已经被替换为装饰器的属性了。如下:

3. 解决方案一

三个函数:

第一个:copy原函数的属性 copy_properties

第二个:装饰器 logger

第三个:功能函数 add

4. 解决方案二

但凡使用装饰器都会出现属性的这个问题,为什么不把copy_properties也做成装饰器呢?

三个函数:

第一个:copy原函数的装饰器 copy_properties1

第二个:装饰器 logger

第三个:功能函数 add

带参装饰器:

推荐↓↓↓

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20181113B1QE1B00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励