装饰器有什么用?
我看了这篇关于装饰器的文章,但我还是不太明白什么时候使用装饰器比较好。
想象一下,有一段代码定义了一个函数f
,然后多次调用它。出于某种原因,我们希望f
能做一些额外的工作。那么我们有两种方法来实现这个目标:
- 定义一个新的函数
g
,它调用f
,并完成所需的额外工作。然后在主代码中,把所有对f
的调用都换成对g
的调用。 - 定义一个装饰器
g
,然后在代码中把@g
加在对f
的调用前面。
最后,这两种方法都能达到相同的效果,但我不太明白第二种方法比第一种方法有什么优势。我是不是漏掉了什么?
1 个回答
2
假设你有很多函数,比如 f1
、f2
、f3
等等,你想要以一种统一的方式对它们进行相同的修改,以便它们都能做一些额外的工作。
这就是你所缺少的东西,也是装饰器(decorators)有用的原因。简单来说,装饰器就是一种函数,它接受一个函数,然后返回一个修改过的版本。
装饰器的 @
语法其实只是为了方便。它让你在定义函数的时候就可以直接装饰这个函数:
@decorated
def foo():
# several lines
而不是在函数定义之后的某个地方:
def foo():
# several lines
foo = decorated(foo)
实际上,后面那种写法是相当糟糕的,因为这样一来,你在源代码中看到的第一个 foo
定义,并不是用户实际调用的那个 foo
。所以如果没有这种语法,装饰器的价值就会大打折扣,因为你几乎总是需要为装饰过的函数和未装饰的函数使用不同的名字。