为什么装饰器函数需要定义自己的函数而不是仅仅运行代码......所以不要这样:
def decor(func):
def wrap():
print("============")
func()
print("============")
return wrap
def print_text():
print("Hello world!")
decorated = decor(print_text)
decorated()
为什么不这样:
def decor(func):
print("============")
func()
print("============")
def print_text():
print("Hello world!")
decorated = decor(print_text)
decorated
答案 0 :(得分:3)
装饰器语法的目的是将函数应用于可调用函数,并生成另一个可调用。在你的第二个例子中,你没有真正的装饰者;您只是将函数引用传递给另一个调用它的函数。
换句话说,与装饰器语法一起使用的函数的的定义特征是它返回另一个函数。装饰器语法没有什么特别之处;它是语法糖,并且它没有任何,你无法用常规Python语法完成。以下
@foo
def bar(...):
...
与完全相同,但更简洁,更明确的形式
def bar(...):
...
bar = foo(bar)
答案 1 :(得分:1)
每次评估时,您的第二个代码块都可以“完成工作”。如果你需要多次这样做怎么办?每次必须评估表达式decor(some_function)
时,即使装饰函数some_function
恰好是同一个东西。如果评估的背景不完全在您的控制范围内会怎样?
使用第一种方法,您基本上将装饰函数包装在可以在以后评估的相同thunk中。你可以在每次需要它时调用相同的thunk。您甚至可以将呼叫委托给其他人。
你的装饰师例子很简单。当代码变得更复杂时,Python将函数作为第一类对象返回的能力是一个福音。一个例子是API需要回调:
def frob(some, args, callback=your_function):
现在,您已经编写了回调函数,并发现memoization可以提升性能。使用装饰器模式,您可以执行类似
的操作my_function_memoized = memoize(my_function, *even_more_parameters_controlling_the_memoization_behavior) # returns decorate function
... ...
frob(some, args, callback=my_function_memoized)
也就是说,装饰的thunk只能在my_function
的位置使用。这在Python中发生了很多,因为Python使得传递callables非常容易。