Python中的装饰器是通过利用了函数特性的闭包实现的,所以在讲装饰器之前,我们需要先了解函数特性,以及闭包是怎么利用了函数特性的
1. 函数特性
python中的函数特性总的来说有以下四点:
1. 函数作为变量传递
def add(x):
return x + 1a = add# 作为变量
说明:函数如果不加括号,是不会执行的,代表的是一个函数对象,它是可以作为变量来传递
2. 函数作为参数传递
def add(x):
return x + 1def execute(f):
return f(3)execute(add)# 作为参数
说明:一个函数可以接受另一个函数对象作为自己的参数,并对函数对象进行处理
3. 函数作为返回值
def add(x):
return x + 1def get_add():
return add# 作为返回值
说明:一个函数的返回值可以是另一个函数对象
4. 函数嵌套及跨域访问
def outer():
x = 1
def inner():
print(x)# 被嵌套函数inner内部的x变量可以到封装域去获取
inner()outer()
说明:一个函数(主函数)内部是可以嵌套另一个函数(子函数)的,比如outer函数从内部嵌套了inner。一个函数本地域没有的变量,是可以跨到它的封装域(主函数与子函数之间的范围)去寻找的
2. 闭包的实现 python中的装饰器是通过闭包实现的,简单地讲,闭包就是引用了外部变量的内部函数,而闭包的实现正是利用了以上函数特性,下面我们来看看闭包是如何实现的:
def outer(x):
def inner():# 函数嵌套
return x# 跨域访问,引用了外部变量xreturn inner# 函数作为返回值closure = outer('外部变量')# 函数作为变量赋给closure
print(closure())# 执行闭包
执行结果:
外部变量
说明:我们分析下这个流程,outer接收到'外部变量',传给inner,作为它return的参数,最后outer返回inner函数,返回的inner函数作为变量传递给closure,最后执行closure这个函数对象,实际上是执行了inner这个函数,返回了 '外部变量',这样就实现了一个简单的闭包
我们发现上面的闭包例子只用到了之前说的其中3个函数特性,函数作为参数 这个特性好像并没用上,别急,我们一步步来,试想一下,outer的参数x是不是也可以是一个函数对象?
下面我们来改写一下实现闭包的代码:
def func():
return '函数func'def outer(x):
def inner():# 函数嵌套
return '戴了inner牌帽子的 ' + x()# 跨域访问,引用了外部变量xreturn inner# 函数作为返回值closure = outer(func)# 函数func作为outer的参数;函数作为变量赋给closureprint(func())# 执行原始函数
print(closure())# 执行闭包
执行结果:
函数func
戴了inner牌帽子的 函数func
说明:我们看到打印的结果, 从 func() 到 closure(),我们是不是感觉函数func被装饰了一番,变成了closure,具体是怎么装饰的呢?
划重点来了!!!!!!!!!!!
我们看到closure实际上是outer(func),func作为参数传进outer,outer的子函数inner对func返回的结果进行了一番装饰,返回了一个装饰后的结果,最后outer返回inner,可以说inner就是装饰后的func,这就是一个函数被装饰的过程,重点在于执行 outer(func) 这个步骤
3. 装饰器语法糖 @ python给我们提供了语法糖 @,我们想执行 outer(func) 的时候,只需要把outer函数@到func函数的上面就可以了
具体实现如下:
def outer(x):
def inner():
return '戴了inner牌帽子的 ' + x()return inner@outer
def func():
return '函数func'print(func())
执行结果:
戴了inner牌帽子的 函数func
说明:我们看到打印的结果跟我们执行closure()的结果是一样的,也就说明 加了outer装饰器的func 等价于 outer(func),所以我们很清楚地知道装饰器@的作用是什么了,就是拿来把被装饰的函数作为参数传递到装饰器函数里面加工的,最后执行被装饰函数的时候,就相当于执行了一个加工后的函数。
以上就是Python中装饰器的诞生过程......
关注公众号【克里斯手册】,了解更多数据相关的内容
文章图片
【只需四步,让你了解Python装饰器的诞生过程】本文由mdnice多平台发布
推荐阅读
- 开源一款监控数据采集器,啥都能监控
- 云上弹性高性能计算,支持生命科学产业高速发展、降本增效
- 阿里云易立(云原生如何破解企业降本提效难题())
- 代码注释的艺术,优秀代码真的不需要注释吗()
- 一文入门玩转windows移动渗透工具包PentestBox
- Java|权限系统控制到按钮级别开源推荐 Spring Boot-Shiro-Vue
- 程序员|大牛深入讲解!Android面试中常问的MMAP到底是啥东东(再不刷题就晚了!)
- 5年磨一剑|优酷Android包瘦身治理思路全解
- 深度思考的重要性