Python的装饰器可以在代码运行时修改函数的上下文,即可以定义函数执行前执行哪些操作以及执行后执行哪些操作函数被执行了,函数本身并没有发生任何改变。
这看起来很复杂,但实际上应用了我之前提到的闭包的概念。仔细一看,其实并不复杂。
首先,我们定义一个函数。这个函数可以输出我的个人昵称:
def my_name(): 打印“Yi_Zhi_Yu” my_name() # Yi_Zhi_Yu
如果我需要在输出个人昵称之前输出我的个人uid怎么办?当然,要求是不要改变现有的my_name函数。这时候就可以使用装饰器了
首先,装饰器也是一个函数。其次,它需要接受一个参数,该参数代表要装饰的函数(即 my_name):
def my_info(func): def 包装器(*args,**params): 打印 218 返回 func(*args, **params) 返回包装器
那么将其与对应的装饰函数关联起来的方法就是使用@my_info写在装饰函数前面
@我的信息 def my_name(): 打印“Yi_Zhi_Yu”
最后,执行my_name时,可以同时输出我的uid和我的昵称
我的名字() 第218章 #Yi_Zi_Yu
上面最让我们困惑的是装饰器函数定义中的包装函数。装饰器本身返回包装函数的定义,包装函数定义了对被装饰函数(my_name)的调用,func表示是被装饰函数。说白了,装饰器只是把某个不能改变的函数(a)放到另一个函数(b)中,在b中调用a,在调用前后都可以做所谓装饰的事情。工作的。
my_info最终返回的包装函数的定义并不是执行结果。只有当包装器真正执行时,my_name方法才会真正执行。这就是结语中所说的。
包装器中的参数实际上是传递给func的参数(实际上是my_name)
因为装饰器也是一个函数,那么装饰器本身可以有参数传递吗?可以,但是需要定义一个高阶函数,即在它外面还有一层函数。比如我也想输出一条我的自定义消息,需要传递参数
def c_info(文本): def my_info(func): def 包装器(*args,**params): 打印文本 打印 218 返回 func(*args, **params) 返回包装器 返回我的信息 #使用装饰器 @c_info(“托尼”) def my_name(): 打印“Yi_Zhi_Yu” 我的名字() #托尼 第218章 #Yi_Zi_Yu
与之前的装饰器相比,只多了一层外层,内层只增加了对外层传入参数(文本)的调用
总而言之,Python支持在函数定义中实现oop思想中的装饰器。它的本质只是利用闭包思想,延迟调用,在调用前后添加自己的其他实现内容