Python装饰器:原函数参数如何传递给wrapper_function?
关于装饰器参数传递的三个问题解答
先还原下Corey视频里的场景,先看踩坑的代码:
def decorator_function(original_function): # 最初的wrapper没定义参数 def wrapper_function(): print(f"Wrapper执行在{original_function.__name__}之前") return original_function() return wrapper_function @decorator_function def display_info(name, age): print(f"display_info运行参数: {name}, {age}") # 调用直接报错:wrapper_function() takes 0 positional arguments but 2 were given display_info("John", 25)
1. 原函数display_info的参数如何传递给wrapper_function?
当你用@decorator_function装饰后,原来的display_info已经被替换成了wrapper_function。也就是说,你写display_info("John", 25)的时候,本质是在调用wrapper_function("John", 25)——你传给原函数的参数,直接就成了wrapper的调用参数。所以必须给wrapper加上*args和**kwargs,才能接住这些任意数量的位置参数和关键字参数。
修正后的代码:
def decorator_function(original_function): # 给wrapper加*args和**kwargs接收参数 def wrapper_function(*args, **kwargs): print(f"Wrapper执行在{original_function.__name__}之前") # 把接收到的参数转发给原函数 return original_function(*args, **kwargs) return wrapper_function @decorator_function def display_info(name, age): print(f"display_info运行参数: {name}, {age}") # 正常执行 display_info("John", 25)
2. 为何仅在返回原函数时传递args和kwargs并不足够?
因为如果wrapper没定义参数,调用的时候直接就触发参数不匹配错误了,根本轮不到执行return original_function(*args, **kwargs)这一步。
比如最初的无参wrapper,你传两个参数调用,Python会直接抛TypeError,连wrapper里的打印语句都不会执行,更别说把参数传给原函数了。只有先让wrapper能接住参数,才有机会把参数转发给原函数。
3. 参数是否是在display_info传入decorator_function时获取的?
完全不是。
装饰器的执行分两个阶段:
- 装饰阶段:Python加载脚本时,会自动执行
decorator_function(display_info),把原函数对象传进去,这时候只是完成了“替换函数”的操作,根本没调用display_info,自然也没有任何参数。 - 调用阶段:只有当你主动调用
display_info("John",25)的时候,才会把参数传给wrapper,这时候参数才真正被获取到。
内容的提问来源于stack exchange,提问作者Evil LLC
相关产品推荐
相关产品推荐

