Python 使用装饰器进行try/except管理

Python 使用装饰器进行try/except管理,python,exception,python-decorators,Python,Exception,Python Decorators,我有一个带有一些低级硬件组件的程序,可能会失败(未初始化、超时、通信问题、无效命令等)。他们生活在一个服务器中,该服务器接收来自webclient的请求 因此,我的想法是使用自定义异常来捕获哪个驱动器中可能出现的故障,这样在某些情况下我可以采取补救措施(例如,如果是通信问题,请尝试重置适配器等),或者在我无法做任何低级操作的情况下冒泡错误,也许是这样,服务器可以向webclient返回一条通用错误消息 例如: class DriveException(Exception): """ Ra

我有一个带有一些低级硬件组件的程序,可能会失败(未初始化、超时、通信问题、无效命令等)。他们生活在一个服务器中,该服务器接收来自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()

我的原型似乎与装饰师配合得很好。然而,我已经搜索了一些关于使用to方法来尝试/例外的信息,并且有点惊讶没有找到太多关于它的信息。人们不这样做有什么好的理由吗?我看不出来?除此之外,它们通常只是将所有内容都包装在一个高级try/catch中&不要再为它操心了?

也许您已经将其简化得太多了,但是原始异常和您在其位置引发的
DriveException
之间的唯一区别是一个常量,它独立于原始异常周围的任何上下文。您没有添加任何不能仅假设与原始内容一起提供的信息。我的想法是,exception类将主要告诉我发生了什么&上下文是什么。我从ex中提出它,以便如果,比如说,我在使用FooDrive时,在某个点上有一个EthernetException,那么它的处理方式可能与使用BarDrive时的处理方式相同,也可能与使用BarDrive时的处理方式不同,或者在每种情况下,我可能不想要/不需要相同的信息……但是,
drive=DriveEnum.KOLLMORGAN
如何告诉您是否每个异常都标记了相同的值?
drive\u exception
的逻辑是否更复杂,以便可以提供不同的值,或者您是否设想了不同版本的函数,以便为
drive
参数硬编码不同的值?Oups-我的错误将得到纠正。它确实没有太多的意义,因为它是。基本上-我有一堆不同的驱动器。一般来说,只为驱动器创建一个泛型类目前可能还可以,但我仍然想知道至少是哪一个。因此,对于每种驱动器类型,我都会有一个不同的装饰器。也许最终我会为每个。。。在这种情况下,装饰师会允许我只在一个地方做。。。而不是在每个单独的try/excape中。。。。