装饰器和闭包有很大的相关性,可以这么说,就是当外部函数后面的参数填入的是另一个函数的名称时(并且最多只能有一个参数),称之为装饰器,也可以说装饰器就是特殊的闭包。 可以用如下方法进行分析:
代码语言:javascript复制def decorator(func):
def inner(a):
print('this is a new method')
func(a)
return inner
def add_1(num):
res = num 1
print(res)
# add_1后面一定不能带括号,带括号代表执行了方法
end = decorator(add_1)
end(1)
这里输出的结果是:
这里就实现了没有改变add_1函数的代码,给该函数增加了一个功能:this is a new method,这就是装饰器的作用,给别的函数增加额外功能而不改变别的函数的代码。 现在做具体的debug分析: 在执行具体命令之前,这两个函数对象已经存储在了内存当中:
下来开始执行end = decorator(add_1)任务(这一步就是关键的装饰环节):
再执行最后一行命令:end(1) 这时直接步入inner函数,说明这时候的end相当于inner对象,而且此时func已经将add_1函数存入:
先执行打印,再执行func(a)
执行func(a)时步入add_1函数:
将结果打印输出,此时func(a)代码执行完毕,end(1)也执行完毕输出结果:
语法糖效果
如果每次装饰函数都要写一个装饰的代码(即end = decorator(add_1)),会略显麻烦,此时我们可以通过下述方法简化代码:
代码语言:javascript复制def decorator(func):
def inner(a):
print('this is a new method')
func(a)
return inner
@decorator
def add_1(num):
res = num 1
print(res)
# add_1后面一定不能带括号,带括号代表执行了方法
add_1(1)
@加装饰器名字即可,输出与第一个示例输出一样。 可以用debug模式下的一个关键步骤解释该语法糖:
在执行add_1(1)这个命令时add_1函数已经成为了一个decorator.inner对象,此时执行的第一步直接是如下步骤: