能否选择单独使用函数或搭配其装饰器?代码场景下的实现方法问询
如何选择调用带装饰器或不带装饰器的函数
当然有办法实现,下面是几种实用的方式:
1. 提前保存原函数引用
在给函数添加装饰器之前,先把原函数赋值给另一个变量,后续需要调用无装饰的版本时直接使用这个变量即可:
def hello_decorator(func): def inner1(*args, **kwargs): print("before Execution") returned_value = func(*args, **kwargs) print("after Execution") return returned_value return inner1 # 先定义并保存原函数 def sum_two_numbers(a, b): print("Inside the function") return a + b original_sum = sum_two_numbers # 再给函数应用装饰器 sum_two_numbers = hello_decorator(sum_two_numbers) a, b = 1, 2 # 调用带装饰器的版本 print("带装饰器的Sum =", sum_two_numbers(a, b)) # 调用无装饰器的原函数 print("无装饰器的Sum =", original_sum(a, b))
2. 利用__wrapped__属性
Python 3.3及以上版本中,被装饰后的函数会自动将原函数引用保存在__wrapped__属性中,直接调用这个属性就能跳过装饰器逻辑:
def hello_decorator(func): def inner1(*args, **kwargs): print("before Execution") returned_value = func(*args, **kwargs) print("after Execution") return returned_value return inner1 @hello_decorator def sum_two_numbers(a, b): print("Inside the function") return a + b a, b = 1, 2 # 调用带装饰器的版本 print("带装饰器的Sum =", sum_two_numbers(a, b)) # 调用原函数,跳过装饰器 print("无装饰器的Sum =", sum_two_numbers.__wrapped__(a, b))
注意:如果是多层装饰器,__wrapped__会指向当前装饰器的上一层函数,需要逐层访问直到拿到最原始的函数。
3. 让装饰器支持开关控制
修改装饰器的实现,添加开关参数来决定是否启用装饰逻辑,实现灵活切换:
def hello_decorator(enable=True): def decorator(func): def inner1(*args, **kwargs): if enable: print("before Execution") returned_value = func(*args, **kwargs) if enable: print("after Execution") return returned_value # 同时保存原函数引用,方便直接调用 inner1.original = func return inner1 return decorator # 启用装饰器 @hello_decorator(enable=True) def sum_two_numbers(a, b): print("Inside the function") return a + b a, b = 1, 2 # 带装饰器调用 print("带装饰器的Sum =", sum_two_numbers(a, b)) # 直接调用原函数 print("无装饰器的Sum =", sum_two_numbers.original(a, b)) # 如果需要临时关闭装饰,也可以重新装饰一次 sum_two_numbers_no_decor = hello_decorator(enable=False)(sum_two_numbers.original) print("临时关闭装饰的Sum =", sum_two_numbers_no_decor(a, b))
内容的提问来源于stack exchange,提问作者Some_Software_Dude
相关产品推荐
相关产品推荐

