Python高效的异常处理

2024-10-01 09:22:48 发布

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

我正在尝试找出是否有一种更适合Python的方法来执行特定的错误处理任务。我希望捕获多个特定的自定义异常,并根据捕获的异常执行特定的操作(如使用特定的自定义退出代码,或添加特定的日志消息等)。但是,如果出现任何异常,我还希望发送一封电子邮件,说明脚本未成功完成,有退出代码,日志位于C:\foo\bar.txt

我知道我可以将我想做的每件事都包括在其中,除了:

try:
    do_something()
except CustomError1:
    exitcode = 1
    send_error_email(exitcode)
    sys.exit(exitcode)
except CustomError2:
    exitcode = 2
    send_error_email(exitcode)
    sys.exit(exitcode)

但我想知道是否有一种更具Python风格或更有效的方法。我在想象这样的事情

try:
    do_something()
except CustomError1:
    exitcode = 1
except CustomError2:
    exitcode = 2
except ParrentCustomErrorClass:
    send_error_email()
    sys.exit(exitcode)

如果这很重要的话,我目前只能使用Python2.7,但需要能够在第三方应用程序允许的情况下将解决方案移植到3.x


Tags: 方法代码send消息emailsysexiterror
2条回答

我见过两个成语:

With finally

exit_code = None
try:
   do_something()
except CustomError1:
    exit_code = 1
except CustomError2:
    exit_code = 2
finally:
    if exit_code is not None:
        send_error_mail(exit_code)

With "dictionary dispatch"

try:
    do_something()
except Exception as e:
    code = {
        CustomError1: 1
        CustomError2: 2
    }.get(type(e))
    if code is None:
        raise
    send_error_email(code)

(或者如果你想全速前进^{}

    ...
    if (code := {
        CustomError1: 1
        CustomError2: 2
    }.get(type(e))) is not None:
         send_error_email(code)
    raise

但是,如果您控制您的异常(它们不是库异常)——我也喜欢@scnerd的解决方案。如果你不想——并且想抓住ValueErrorTypeError或其他什么,那么其中一个就是要走的路

您能在异常类型本身中定义退出代码吗

class ParentCustomErrorClass(Exception):
    exitcode = 999

    def send_error_email(self):
        raise NotImplementedError()

    def die_horribly(self):
        import sys
        self.send_error_email()
        sys.exit(self.exitcode)

class CustomError1(ParentCustomErrorClass):
    exitcode = 1

class CustomError2(ParentCustomErrorClass):
    exitcode = 2

try:
    do_something()
except ParentCustomErrorClass as ex:
    ex.die_horribly()

相关问题 更多 >