Python嵌套装饰器内部如何获取被装饰的原始函数引用
多层装饰器获取原始目标函数的解决方案
实现思路
Python标准库本身就提供了原生支持,不需要依赖栈帧解析这类不稳定的实现:
functools.wraps装饰包装函数时,会自动为包装函数添加__wrapped__属性,指向被装饰的原函数- 多层装饰场景下,每一层的包装函数都会保留指向其传入函数的
__wrapped__,形成完整的装饰链式引用 - Python 3.3+ 版本的
inspect模块内置unwrap方法,可以自动递归拆解所有__wrapped__属性,直接返回最底层的原始目标函数
可运行代码示例
import inspect from functools import wraps def test_decorator(func): @wraps(func) def wrapper(*args, **kwargs): # 一行代码获取最原始的被装饰函数 original_func = inspect.unwrap(func) print(f"当前装饰层获取到的原始函数:{original_func.__name__}") return func(*args, **kwargs) return wrapper @test_decorator @test_decorator @test_decorator def test_func(a, b, c): print("func") test_func(1,2,3)
运行后可以看到三层装饰器都能直接获取到最原始的test_func引用。
注意事项
- 该方案依赖所有装饰器都规范使用
@wraps(func)装饰内部的包装函数,否则会因缺少__wrapped__属性无法完整拆解装饰链 - 如果你需要兼容未使用
wraps的特殊装饰器场景,可以给inspect.unwrap传入stop参数自定义终止判断逻辑,满足自定义拆解需求
内容的提问来源于stack exchange,提问作者winwin
相关产品推荐
相关产品推荐

