我很难抓住装饰器,我最初认为装饰器是语法糖来做一个操作,如:
def decorator(x):
return x*2
@decorator
def plusone(x):
return x+1
print plusone(5)
# would print twelve, because: decorator(plusone(5)) as I have seen
# in some tutorials
但我注意到首先需要在装饰器中创建包装函数。
为什么我们需要返回一个函数,而不是一个整数?
答案 0 :(得分:3)
(Python)装饰器是修改函数的函数的语法糖,导致后者函数就像自身的修改版本一样。
让我们从一个简单(并不是那么好)的例子开始。说我们写
def double_me(f):
return lambda x: 2 * f(x)
它接受一个带一个参数的函数,并返回一个带有一个参数的函数,并返回原始函数返回的double。然后我们可以像这样使用它:
def double_the_add_one(x):
return x + 1
double_the_add_one = double_me(double_the_add_one)
>>> double_the_add_one(1)
4
请注意,我们首先定义double_the_add_one
,然后修改double_the_add_one
并将其绑定回double_the_add_one
。所以现在它只是它自身的一个修改版本 - 它完成了原来的工作,然后只是将结果加倍。装饰者只是简单地说明了这一点:
@double_me
def double_the_add_one(x):
return x + 1
>>> double_the_add_one(1)
4
请注意,上面的装饰者并不是那么好:
它假设有一个位置参数。
它假设没有关键字参数。
如果装饰的函数有文档字符串,则会被破坏。
你应该使用functools.wraps
来实际编写装饰器,使用那里的文档中的例子。