如何在Python装饰器中访问被装饰函数内部变量以实现验证?
能不能从装饰器访问被装饰函数的局部变量?
不行,你没法直接从装饰器里拿到被装饰函数内部的answer变量——因为局部变量的作用域只限于函数内部,函数执行结束后这些变量就会被Python的垃圾回收机制处理掉,装饰器里的wrapper函数根本碰不到它们。
不过有几种可行的替代方案,能实现你要的验证需求:
方案1:让被装饰函数返回需要验证的变量
这是最直观的方式,修改原函数让它返回要验证的变量,然后在装饰器的wrapper里接收这个返回值再做验证:
from functools import wraps def validation_func(func): @wraps(func) def wrapper(*args, **kwargs): # 接收原函数返回的变量 answer = func(*args, **kwargs) # 执行验证逻辑 if answer == 1337: print('1337') else: print('Hi') # 可选:把结果返回,不影响原函数的正常使用 return answer return wrapper @validation_func def math_add(): answer = 1336 + 1 return answer # 返回需要验证的变量 math_add() # 输出:1337
方案2:把变量绑定为函数的属性
如果不想让原函数返回值(比如原函数本来就有其他返回逻辑),可以把要验证的变量绑定到函数自身的属性上,这样装饰器就能通过函数对象访问到:
from functools import wraps def validation_func(func): @wraps(func) def wrapper(*args, **kwargs): func(*args, **kwargs) # 先判断属性是否存在,避免报错 if hasattr(func, 'answer') and func.answer == 1337: print('1337') else: print('Hi') return wrapper @validation_func def math_add(): answer = 1336 + 1 math_add.answer = answer # 把局部变量绑定为函数的属性 math_add() # 输出:1337
为什么你的原代码不行?
你原代码里的wrapper.answer根本没有定义,而且math_add里的answer是局部变量,和wrapper函数的作用域完全隔离,所以装饰器根本找不到这个变量。
内容的提问来源于stack exchange,提问作者antje668
相关产品推荐
相关产品推荐

