Python装饰器的诞生过程:使用函数属性实现闭包
Python中的装饰器是通过使用函数属性的闭包来实现的,所以在谈论装饰器之前,我们首先应该了解函数属性和闭包。如何利用函数属性
① 函数属性
一般来说,Python 中的函数属性有以下四点:
1。函数作为变量传递
def add(x):
return x + 1
a = add # 作为变量
说明:如果函数不包含括号,则不会执行,代表一个函数对象,可以作为变量传递
2。函数作为参数传递
def add(x):
return x + 1
def execute(f):
return f(3)
execute(add) # 作为参数
说明:一个函数可以接受另一个函数对象作为自己的参数,并通过函数对象进行处理
3。函数作为返回值
def add(x):
return x + 1
def get_add():
return add # 作为返回值
说明:一个函数的返回值可以是另一个函数对象
4。函数嵌套和跨域访问
def outer():
x = 1
def inner():
print(x) # 被嵌套函数inner内部的x变量可以到封装域去获取
inner()
outer()
说明:一个函数(主函数)内部可以嵌套另一个函数(子函数)。例如,inner从内部嵌套外部函数。不在函数局部域中的变量可以在封装域(主函数和子函数之间的范围)中找到
②闭包的实现
Python中的装饰器可以通过闭包轻松实现总之,闭包是一个引用外部变量的内部函数,闭包的实现使用了上述函数属性。我们来看看闭包是如何实现的:
def outer(x):
def inner(): # 函数嵌套
return x # 跨域访问,引用了外部变量x
return inner # 函数作为返回值
closure = outer('外部变量') # 函数作为变量赋给closure
print(closure()) # 执行闭包
执行结果:
外部变量
说明:我们来分析一下这个过程。 external 接收“外部变量”并将其作为返回参数传递给 inner。最后outside返回inner的函数,返回的inner的函数作为变量传递给closure,最后执行闭包函数对象。 ,实际上执行了inner函数并返回“外部变量”,实现了一个简单的闭包
我们发现上面的闭包示例只使用了前面提到的三个函数属性。该函数就像 看起来参数函数没有被使用。别担心,我们一步一步来。想象一下:outside的参数x可以是一个函数对象吗?
我们重写一下代码来实现闭包:
def func():
return '函数func'
def outer(x):
def inner(): # 函数嵌套
return '戴了inner牌帽子的 ' + x() # 跨域访问,引用了外部变量x
return inner # 函数作为返回值
closure = outer(func) # 函数func作为outer的参数;函数作为变量赋给closure
print(func()) # 执行原始函数
print(closure()) # 执行闭包
执行结果:
函数func
戴了inner牌帽子的 函数func
说明:当我们看到打印结果,从func()到closure(),是不是感觉func函数已经被配置了?这将是一个关闭。装修如何?
最重要的一点来了! ! ! ! ! ! ! ! ! ! !
我们看到闭包其实是outside(func),func作为参数传入outside,outer的子函数inner对func返回的结果进行修饰,返回一个修饰后的结果,最后outside返回inner。可以说,inner就是装饰func。这是设置函数的过程。重点是执行外部(func)步骤
③装饰器语法sugar@
Python为我们提供了语法sugar@。如果我们想执行outside(func),我们只需要把outside function@放在func函数上面即可。
具体实现如下:
def outer(x):
def inner():
return '戴了inner牌帽子的 ' + x()
return inner
@outer
def func():
return '函数func'
print(func())
执行结果:
戴了inner牌帽子的 函数func
说明:我们看到打印的结果和我们运行closure()时的结果是一样的,也就是说func和外层装饰器是等价的到外面(func),所以我们清楚地知道装饰器。 @的作用是什么?它用于将被装饰函数作为参数传递给装饰器函数进行处理。当被修饰的函数最终被执行时,就相当于执行了一个被处理的函数。
以上就是Python中装饰器的诞生过程...
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。