我想实现一种方法来全局处理通过我的应用程序发出的类中的异常,而不是在调用站点处处理它们,因为这将导致大量重复代码。
例如,假设我有一个像这样的课程:
class handler():
def throws_value_error(self):
raise ValueError
def throws_not_implemented_error(self):
raise NotImplementedError
# ... Imagine there are hundreds of these
在此处理程序类中,我希望所有ValueError
和NotImplementedError
都以相同的方式进行处理-一条消息显示[ERROR]: ...
,其中...
是来自特定实例的详细信息。
而不是再现TON:
try:
#...
except Exception as e:
# Catch the instances of the exception and handle them
# in more-or-less the same way here
我想在类上实现一个可实现此目的的单一方法:
def exception_watcher(self):
# Big if...elif...else for handling these types of exceptions
然后,在类中提供任何Exception
时将调用此方法。
我的动机是使用它来实现一种通用的控制器接口,其中控制器方法可以抛出异常的子类(例如-BadRequestException
,它是Error400Exception
的子类)。从那里,处理程序可以调度一种方法,以使用针对异常类型的错误代码正确地配置响应,并另外向消费者返回有用的答复。
很明显,没有此调度程序,这是可行的-但这种方式肯定可以节省大量重复代码(并因此减少错误)。
我已经在互联网上进行了很多挖掘工作,但没有发现任何东西。诚然,我从Spring Boot Framework借用了这种模式。我也将接受非Python语言作为答案(只要您能告诉我正确的方法!)
任何帮助将不胜感激-谢谢!
答案 0 :(得分:1)
在不更改其核心功能的情况下修改功能正是装饰器的目的。看一下此示例,然后尝试运行它:
def catch_exception(func):
def wrapped(self, *args, **kwargs):
try:
return func(self, *args, **kwargs)
except ValueError:
self.value_error_handler()
except NotImplementedError:
self.ni_error_handler()
return wrapped
class Handler:
def value_error_handler(self):
print("found value error")
def ni_error_handler(self):
print("found not implemented error")
@catch_exception
def value_error_raiser(self):
raise ValueError
@catch_exception
def ni_error_raiser(self):
raise NotImplementedError
h = Handler()
h.value_error_raiser()
h.ni_error_raiser()
由于使用了@catch_exception
装饰器,因此装饰后的方法不会引发经过校准的错误;而是调用wrapped
的try / except块中定义的相应方法,并打印一条消息。
虽然这并非您所要求的,但我认为此解决方案总体上更易于管理。您既可以选择要定期引发异常的方法,又可以选择catch_exception
处理哪些方法(通过确定修饰的方法),还可以通过在内部编写额外的except
块来增加其他异常类型的未来行为wrapped
,并将相应的方法添加到Handler
类中。
请注意,这不是一个“干净”的解决方案,因为wrapped
希望知道self
是Handler
的一个实例,因为它调用了很多方法,甚至虽然它是Handler
类之外的一个函数...但是,嘿,那是Python的鸭子为您输入的:-P