子类通过super调用父类方法时如何跳过其@validate装饰器?
解决方案:跳过父类方法的装饰器调用
这个问题挺常见的——当子类重写了带装饰器的父类方法,又想在子类方法里调用父类的原始逻辑而不触发装饰器时,确实需要点小技巧。下面给你两种可行的实现方案:
方案一:修改装饰器,保留原始方法引用
核心思路是让装饰器把未被装饰的原始方法保存为装饰后函数的一个属性,这样后续就能直接获取并调用这个原始方法。
首先调整@validate装饰器的实现:
def validate(func): def wrapper(*args, **kwargs): print("执行验证逻辑...") return func(*args, **kwargs) # 将原始方法绑定到装饰后的wrapper函数上 wrapper._original_method = func return wrapper
然后在子类B中,直接调用父类A的原始方法,而不是通过super()调用被装饰后的版本:
class A: @validate def test(self): print("执行A类的test方法逻辑") class B(A): @validate def test(self): # 获取A类test方法的原始未装饰版本 a_original_test = A.test._original_method # 调用原始方法,注意传入self作为第一个参数 a_original_test(self) print("执行B类的test方法逻辑")
测试调用B().test()时,只会触发B类的@validate装饰器,而A类的test方法会直接执行原始逻辑,跳过它的装饰器验证。
方案二:拆分父类方法,分离装饰器与核心逻辑
如果不能修改@validate装饰器的代码,可以在父类A中把核心逻辑拆到一个未被装饰的方法里,让被装饰的test()方法调用这个核心方法。这样子类就能直接调用核心逻辑,绕过装饰器。
代码示例:
class A: # 存放原始核心逻辑的方法,不添加装饰器 def _test_core(self): print("执行A类的test方法核心逻辑") @validate def test(self): # 被装饰的方法只负责调用核心逻辑 self._test_core() class B(A): @validate def test(self): # 直接调用父类的核心逻辑方法,跳过装饰器 self._test_core() print("执行B类的test方法逻辑")
这种方式不需要修改装饰器,通过方法拆分实现了绕过装饰器的目的,代码结构也更清晰。
为什么直接用super()不行?
当你调用super(B, self).test()时,拿到的是父类A中已经被@validate装饰后的test方法,所以执行时必然会触发父类的装饰器逻辑。我们的方案本质上都是绕开这个被装饰后的方法,直接获取并执行原始的核心逻辑。
内容的提问来源于stack exchange,提问作者Albin Antony
相关产品推荐
相关产品推荐

