Python带参数装饰器疑问:func、return及函数替换问题咨询
Python装饰器核心疑问拆解
嘿,我懂装饰器一开始绕得人头疼的感觉!先结合你贴的代码,逐个把你的疑问掰碎了讲清楚:
你的三个核心问题解答
1. @functools.wraps(func)中的func具体指什么?
这个func就是你被装饰的原函数——也就是例子里的my_function_too。当你用@decorator_with_arguments(57)装饰my_function_too时,程序会先把my_function_too作为参数传给my_decorator,这里的func就是它的别名。
functools.wraps的作用很实用:它会把原函数的元信息(比如函数名、注释文档)“拷贝”到装饰后的新函数上。要是不用它,你打印my_function_too.__name__会得到function_that_runs_func,而不是原来的函数名,调试的时候会特别懵。
2. 此处为何需要编写return function_that_runs_func和return my_decorator?
这得从带参数装饰器的执行流程说起,本质是“两步走”:
- 第一步:
@decorator_with_arguments(57)这行代码,本质是先调用decorator_with_arguments(57),这个函数是个装饰器工厂,它需要返回一个真正能包装函数的装饰器——也就是my_decorator,所以必须写return my_decorator。要是不返回,后续就没法把my_function_too传给装饰器了。 - 第二步:
my_decorator接收了my_function_too作为func后,内部定义了function_that_runs_func(这才是真正包裹原函数逻辑的“新函数”),必须返回这个函数,才能让原来的my_function_too变量指向这个新函数。要是不返回,装饰完之后my_function_too就变成None了,调用它直接报错。
简单说:外层返回装饰器,内层返回包裹函数,这是带参数装饰器的固定套路。
3. function_that_runs_func()会替换my_function_too()的含义及原因
这个说法完全正确!咱们一步步拆解执行过程:
- 当你把
@decorator_with_arguments(57)写在my_function_too上面时,程序先执行decorator_with_arguments(57),得到返回的my_decorator函数。 - 接着,把
my_function_too作为参数传给my_decorator,my_decorator内部定义了function_that_runs_func,然后返回这个函数。 - 最后,程序会把原来指向
my_function_too的变量名,重新指向function_that_runs_func。
所以当你调用my_function_too(57,67)时,其实调用的是function_that_runs_func(57,67)——原函数my_function_too还在内存里,但你通过原来的名字访问到的已经是装饰后的新函数了。这就是装饰器的核心:在不修改原函数代码的前提下,给它套一层额外逻辑。
修正后的完整代码
(注:原代码漏了import functools和函数定义的冒号,这里补上了)
import functools def decorator_with_arguments(number): def my_decorator(func): @functools.wraps(func) def function_that_runs_func(*args,**kwargs): print("In the decorator") if number == 56: print("Not running the function") return None else: print("Running the 'real' func") return func(*args,**kwargs) return function_that_runs_func return my_decorator @decorator_with_arguments(57) def my_function_too(x,y): print(x+y) my_function_too(57,67)
执行输出
In the decorator
Running the 'real' func
124
内容的提问来源于stack exchange,提问作者anonymous
相关产品推荐
相关产品推荐

