使用decorator进行try/except管理

2024-05-18 11:05:21 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个带有一些低级硬件组件的程序,可能会失败(未初始化、超时、通信问题、无效命令等)。它们位于一个服务器中,该服务器接收来自webclient的请求

因此,我的想法是使用自定义异常来捕获哪个驱动器中可能出现的故障,以便在某些情况下采取补救措施(例如,如果是通信问题,请尝试重置适配器等),或者在无法执行任何低级操作的情况下,将错误冒泡出来,这样服务器就可以向webclient返回一个通用错误消息

例如:

class DriveException(Exception):
    """ Raised when we have a drive-specific problem """
    def __init__(self, message, drive=None, *args):
        self.message = message
        self.drive = drive
        super().__init__(message, drive, *args)

但是这个驱动器可能有问题,比如说,以太网连接没有响应:

class EthernetCommException(Exception):
    """ Raised when ethernet calls failed  """

在代码中,我可以确保我的异常以这种方式出现:

   # ... some code .... 
   try:
        self.init_controllers()         # ethernet cx failed, or key error etc.
    except Exception as ex:
        raise DriveException(ex) from ex
   # .... more code.... 

我在服务器中进行了高级try/except,以确保它不断响应请求&;在低级别组件没有响应的情况下不会崩溃。那个机修工工作得很好

但是,我有许多不同的驱动器。我宁愿避免在代码中的任何地方都添加try/except。我现在的想法是:

def koll_exception(func):
    """ Raises a drive exception if needed """
    @functools.wraps(func)
    def wrapper_exception(*args, **kwargs):
        try:
            value = func(*args, **kwargs)
            return value
        except Exception as ex:
            raise DriveException(ex, drive=DriveEnum.KOLLMORGAN) from ex
    return wrapper_exception

这样我就可以:

@koll_exception
def risky_call_to_kolldrive():
    #doing stuff & raising a drive exception if anything goes wrong


# then anywhere in the code
foo = risky_call_to_kolldrive()

我的原型机似乎和装饰师配合得很好。然而,我已经搜索了一些关于使用toapproach来try/except的信息,对于没有找到太多信息感到有些惊讶。我不明白为什么人们不这么做?除此之外,他们通常只是将所有内容包装在一个高级的try/catch&;中;不用多操心了


Tags: self服务器messageinitdefexception情况args