从上述回答中的几个有助于装饰器理解的 关键点:
定义
阶段而不是 执行
阶段。函数定义
。now = foo(now)
。如果没有嵌套,实际上装饰器返回的要么是原函数的定义,要么根本不是函数,也就是说函数根本没有被装饰。
即使碰巧得到了想要的结果也是装饰器在定义的阶段便运行的,这其实是不应该发生的,因为这意味着不调用函数,照样会有输出,而且效果不能在函数被调用时复现。
代码说明如下
def foo(func): # 装饰器内部无嵌套
print ("[INFO]: now exe {}()".format(func.__name__))
return func
@foo
def hello(x):
print ("hello {}!".format(x))
此时直接运行上述代码是会打印出[INFO]: now exe hello()
的,然而此处并没有调用hello
如果碰巧在上述代码末尾加上了hello(x="world")
,那么将会输出:
[INFO]: now exe hello()
hello world!
这完全足以以假乱真了,实际情况是定义阶段产生了第一条输出,真正调用时只产生了第二条。
def foo(func): # 装饰器内部有嵌套
def wrapper(*args, **kwargs):
print ("[INFO]: now exe {}()".format(func.__name__))
return func(*args, **kwargs)
return wrapper
@foo
def hello(x):
print ("hello {}!".format(x))
hello("world")
装饰器等于修改了原函数定义,返回的仍然是函数定义!而不是单纯的返回的函数运行结果。
此时再调用被装饰函数实际执行的是已经被装饰过的函数(即可以理解为调用具有装饰器的函数,该函数的实际定义已经不是你看到的定义,而是被装饰器修改后的)
一次定义后即可重复使用,就像普通定义函数一般。
个人以为如果用装饰器,又不嵌套的写法是完全有悖装饰器初衷的,这时大可不必用装饰器,还不如直接函数调用来的实在。
如果对装饰器不甚了解或者想了解更多,推荐下面的链接:为什么需要装饰器