当我们在函数内部编写函数时,为什么不调用它呢?回报如何称呼它?
def my_decorator(func):
def wrapper():
print("Something is happening before the function is called.")
func()
print("Something is happening after the function is called.")
return wrapper
为什么用return wrapper代替return wrapper()?以及包装器必须接受参数时我们该怎么做?
答案 0 :(得分:2)
函数可以像Python中的值一样对待
def foo():
print("Hello World!")
x = foo
x()
是有效的Python,将打印出Hello World!
扩展这个想法...如果我们想在调用函数之前做点什么?好吧,我们可以这样做:
def foo():
print("Hello World!")
def do_something_before():
print("something before")
foo()
x = do_something_before
x()
但是我们已经将自己锁定为只能使用foo函数。如果我们想为bar
或foobar
或任意数量的功能做“事前准备”怎么办?
我们将其参数化!并且由于我们要在“正常”函数上添加额外的位,即装饰它,所以我们将此新函数称为装饰器。
def foo():
print("Hello World!")
def do_something_before(func): # the decorating function
def wrap():
print("something before")
func()
return wrap
x = do_something_before(foo)
x()
然后,Python允许我们在任何需要的地方使用语法糖来执行此操作:
def my_decorator(func):
def wrapper():
print("Something is happening before the function is called.")
func()
print("Something is happening after the function is called.")
return wrapper
@my_decorator
def foo():
print("Hello World!")
装饰器必须接受一个函数,然后允许再次调用它,因此,我们将直接返回带有foo的函数,而不是直接调用foo,以便稍后在调用foo时调用。我们实际上正在调用包装器,由foo返回。如果在装饰器中调用wrapper
,则将返回wrapper
的结果,而不是wrapper
本身。这意味着我们以后不能调用foo()
,因为实际上没有要调用的函数。
我们可以添加这样的参数:
def my_decorator(func):
def wrapper(*args):
print("Something is happening before the function is called.")
func(*args)
print("Something is happening after the function is called.")
return wrapper
含义my_decorator
现在可以修饰任何功能。我们还可以指定特定数量的参数。
答案 1 :(得分:1)
装饰器用于将功能替换为其他功能,通常是通过某种方式修改原始功能的行为。因此,装饰器必须返回一个应调用的函数,而不是原始函数。
如果返回了wrapper()
,则只需调用一次新的wrapper
函数并返回结果。但是您真正需要做的是将func
替换为wrapper
,这样,每当有人呼叫func
时,他们实际上会呼叫wrapper
,然后呼叫{ {1}}。因此func
本身必须返回my_decorator
,而不是wrapper
的输出。然后,当您使用wrapper()
作为修饰符时,Python每次都会自动调用my_decorator
而不是原始函数。
wrapper
函数应始终使用与wrapper
相同的参数。因此,如果需要参数,只需使用与func
行中的func
相同的参数进行定义即可。