Python 装饰器为什么难理解?

发布时间:
2023-08-24 12:41
阅读量:
15

我觉得不难理解啊。

# 函数封装与调用

一般情况下,我们会把成套的代码封装成一个一个的函数,这样方便我们调用。

def 我是函数呀(): print('hello world !') # 直接调用函数 我是函数呀()

这一段代码很直接,就是 hello world !

中间商

现在我们加个中间商角色,通过中间商来调用函数。如下:

def 我是中间商(函数: callable): return 函数 def 我是函数呀(): print('hello world !') # 调用中间商 我是中间商(我是函数呀)()

这个代码和上面的直接调用函数的代码,运行结果是一样的,但代码有点脱裤子放屁了。

其实,我们有了中间商的角色,我们就可以在中间商环节里动手脚了,例如我们在中间商里加点盐,代码如下:

def 我是中间商(函数: callable): print('没想到吧,我给你加点盐') return 函数 def 我是函数呀(): print('hello world !') def 我也是函数呀(): print('hello world again !') # 调用中间商 我是中间商(我是函数呀)() print('-' * 50) 我是中间商(我也是函数呀)()

中间商代码在执行函数前,加了点盐。我们代码中通过中间商调用了两个函数,这两个函数都加了盐。

中间商加盐

所以你可以通过中间商在函数执行前做一些共性的操作,例如 打印log。中间商还是很有用的。这一点都不脱裤子放屁。

中间商有点麻烦

我们通过 我是中间商(我是函数呀)()这种格式调用函数,总是多写了 我是中间商 这部分调用,并且这种通过中间商调用函数的格式是完全统一的,有没有什么办法让他自己把中间商套上呢?

答案是有的,既然格式是完全统一的,编译器/解释器 给我们做了个语法糖,通过在函数定义前面加个 @ 符号,编译器/解释器自动在调用函数函数时,转换成 我是中间商(我是函数呀)()这种格式。像这种:

# 装饰器 @我是中间商 def 我是函数呀(): print('hello world !')

作为对比,以下代码中两个方法,两种不同的调用方式,效果是一样的。

def 我是中间商(函数: callable): print('没想到吧,我给你加点盐') return 函数 @我是中间商 def 我是函数呀(): print('hello world !') def 我也是函数呀(): print('hello world again !') # 调用中间商 我是函数呀() print('-' * 50) 我是中间商(我也是函数呀)()

我是函数呀前面加了 @我是中间商,这相当于告诉了编译器/解释器,我在调用 我是函数呀的时候,你帮我套个 我是中间商的壳,这样就避免了手动套壳(重复的工作总是那么的low)。

下图的运行结果也证明了,自动套壳,和手动套壳,效果是一样的。

自动套壳,手动套过壳

另外,我们注意到,通过 @ 告诉编译器/解释器 来自动套壳,让我们在调用函数时,保留了函数原始的形态,原汁原味的函数,总是那么的舒心。

@我是中间商 这就是装饰器

推而广之

以上就是装饰器的简单形态了。

其实你也看到了,不可能所有的函数都没有参数,如果函数有参数怎么办?

其中,有了基础形态,为了支持带参函数的装饰,甚至中间商本身也带参数,都是支持的。为了支持这些特性, 装饰器的定义演化出了一层又一层壳。但万变不离其宗,装饰器本质就是个中间商,不能因为它穿上了华贵的衣服,你就不认识它了。

最后

最后,补个图吧,通过 print 对齐打印的方式,打印条形图。

DebugInfo 模块打印条形图

END