Python 装饰器为什么要双层嵌套

参考链接:
  1. python装饰器为什么要双层嵌套函数
  2. python装饰器为什么要双层嵌套

从上述回答中的几个有助于装饰器理解的 关键点:

  • 装饰器发生在 定义 阶段而不是 执行 阶段。
  • 装饰器返回的是一个被装饰过的 函数定义
  • 结合第二点理解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")

解释:

装饰器等于修改了原函数定义,返回的仍然是函数定义!而不是单纯的返回的函数运行结果。

此时再调用被装饰函数实际执行的是已经被装饰过的函数(即可以理解为调用具有装饰器的函数,该函数的实际定义已经不是你看到的定义,而是被装饰器修改后的)

一次定义后即可重复使用,就像普通定义函数一般。

个人以为如果用装饰器,又不嵌套的写法是完全有悖装饰器初衷的,这时大可不必用装饰器,还不如直接函数调用来的实在。

更多

如果对装饰器不甚了解或者想了解更多,推荐下面的链接:为什么需要装饰器

你可能感兴趣的:(Python使用,python,装饰器,decorator)