Python装饰器修饰函数的参数工作原理及代码运行疑问咨询
装饰器参数传递逻辑说明
首先明确Python装饰器的核心执行逻辑:@math_test 语法糖等价于执行了 times10 = math_test(times10),也就是说你最终调用的times10不是最初定义的接收x参数的原函数,而是math_test返回的wrapper函数,所有参数传递规则都以wrapper的实现为准。
第一个版本的运行逻辑解释
你第一个版本的wrapper实现如下:
def wrapper(*args, **kwargs): func(var)
- 不管调用
times10时是否传入参数,wrapper都只会把全局变量var作为固定参数传给原times10函数,所以调用times10()不传参数也能正常运行,因为参数是你直接写死在wrapper内部的,不需要从外部获取。 - 你之前写
func()不传参数时的报错,是因为原times10要求必须传入1个位置参数x,没有传入自然会触发缺参数错误。 - 你尝试调用
times10(var)也报相同错误,是因为即使你给wrapper传了参数,你也没有在wrapper的实现里把收到的参数传给func,func还是没拿到符合要求的入参。
你的认知偏差点
你认为wrapper会自动把传入times10的参数作为func的入参,这个逻辑的方向是对的,但参数传递不是自动完成的,需要你手动在wrapper里把收到的参数转发给func。你第一个版本的wrapper只写死了传var,完全没有用到自己接收的*args和**kwargs,自然拿不到外部传入的参数。
修改后版本正常运行的原因
你修改后的wrapper实现是func(*args, **kwargs),相当于把调用wrapper时收到的所有位置参数、关键字参数原封不动转发给原times10函数。这时候你调用times10(var),var会先被wrapper的*args接收,再转发给原times10的形参x,自然可以正常运行。
内容的提问来源于stack exchange,提问作者Savvas Nicolaou
相关产品推荐
相关产品推荐

