Python中被装饰器包装后如何保留原功能、调用无装饰效果的原函数?
Python装饰器包装后保留原函数功能的方法
你给出的代码中,装饰器dec_sub在函数定义阶段就替换了sub指向的对象,默认直接调用sub走的都是包装后的逻辑。要不受装饰器影响调用原始的sub函数,有两种主流实现方案:
方案1:在装饰器内绑定原函数为包装函数的属性
修改装饰器逻辑,把原始函数作为属性挂载到返回的包装函数上,后续可以直接通过该属性调用原函数:
def dec_sub(func): def wrapper(a, b): if a < b: a, b = b, a return func(a, b) # 绑定原函数到包装函数的属性上 wrapper.original = func return wrapper @dec_sub def sub(a, b): c = a - b return c # 调用装饰后的逻辑 print(sub(1, 8)) # 输出7 # 调用原函数逻辑 print(sub.original(1, 8)) # 输出-7
方案2:不使用@语法糖,手动保留原函数引用
@语法糖本质是定义函数后自动执行sub = dec_sub(sub),你可以手动完成这个过程,单独保留原函数的引用:
def sub(a, b): c = a - b return c def dec_sub(func): def wrapper(a, b): if a < b: a, b = b, a return func(a, b) return wrapper # 手动装饰,单独保留原函数和装饰后函数的引用 sub_decorated = dec_sub(sub) # 调用装饰后的逻辑 print(sub_decorated(1, 8)) # 输出7 # 调用原函数逻辑 print(sub(1, 8)) # 输出-7
补充说明
如果已经用@语法糖完成装饰,且装饰器内没有提前绑定原函数属性,就无法再获取到原始的sub函数了,因此需要保留原函数能力的场景建议提前按上述两种方案处理。
内容的提问来源于stack exchange,提问作者Kittu27
相关产品推荐
相关产品推荐

