我试图用 same exception_wrapper.
包装从抽象类 (D) 继承的所有子类 (E, F) 方法我试图包装抽象类方法,因为子类方法覆盖了抽象方法,所以它们没有用
exception_wrapper
.
如何在不从子类中声明它的情况下包装抽象类中的所有子类方法?
from abc import ABCMeta, abstractmethod
import functools
class D(metaclass=ABCMeta):
def __init__(self, a):
self.a= a
@abstractmethod
def b(self, **kwargs):
raise NotImplementedError
@abstractmethod
def c(self, **kwargs):
raise NotImplementedError
def exception_wrapper(func):
@functools.wraps(func)
def func_wrapper(self, *args, **kwargs):
try:
return func(self, *args, **kwargs)
except Exception as ex:
self.loggerservice.info(str(ex))
return func_wrapper
class E(D):
def __init__(self, a):
super().__init__(a=a)
@exception_wrapper
def b(self, **kwargs):
return 1
@exception_wrapper
def c(self, **kwargs):
return 2
class F(D):
def __init__(self, a):
super().__init__(a=a)
@exception_wrapper
def b(self, **kwargs):
return 1
@exception_wrapper
def c(self, **kwargs):
return 2
在这里,我将展示如何访问
D
的子类并应用包装器。我假设您想包装所有与在 @abstractmethod
中用 D
装饰的方法同名的方法。
class D(metaclass=ABCMeta):
...
def __init_subclass__(cls, **kwargs):
for name_of_func_to_wrap in D.__abstractmethod__:
setattr(
cls,
name_of_func_to_wrap,
exception_wrapper(
cls.__dict__[name_of_func_to_wrap]
)
)
__init_subclass__
在定义 D 的子类后立即调用,这非常适合这个问题。 https://docs.python.org/3/reference/datamodel.html#customizing-class-creation
@abstractmethod
是一个非常简单的装饰器。它只是向函数添加一个属性并返回它。 ABCMeta 然后寻找这个标记并创建 __abstractmethod__
来跟踪它们。创建自己的装饰器并更有选择性地包装函数是微不足道的。
如果直接子类没有实现所有抽象方法,这将失败。如果处理得当,它仍然不会处理在子类中定义新的抽象方法。