用相同的包装器包装从抽象类继承的所有子类方法

问题描述 投票:0回答:1

我试图用 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
python class exception wrapper abstract
1个回答
0
投票

在这里,我将展示如何访问

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__
来跟踪它们。创建自己的装饰器并更有选择性地包装函数是微不足道的。

进一步增强

如果直接子类没有实现所有抽象方法,这将失败。如果处理得当,它仍然不会处理在子类中定义新的抽象方法。

© www.soinside.com 2019 - 2024. All rights reserved.