Python 使用异常链接的原因是什么

Python 使用异常链接的原因是什么,python,python-3.x,exception,Python,Python 3.x,Exception,最近我读到了关于异常链接的文章,我不确定什么时候应该使用这种语法,以及出于什么原因 我习惯了这样的模式: try: my_function() exception MyError: my_logger.exception("Error occured") raise MyProcessError("Process failed") 我注意到,如果我在这里使用异常链接,回溯中的一个文本将被更改,MyProcessError将具有新的

最近我读到了关于异常链接的文章,我不确定什么时候应该使用这种语法,以及出于什么原因

我习惯了这样的模式:

try:
    my_function()
exception MyError:
    my_logger.exception("Error occured")
    raise MyProcessError("Process failed")
我注意到,如果我在这里使用异常链接,回溯中的一个文本将被更改,MyProcessError将具有新的属性,其中包含来自MyError的消息

try:
    my_function()
exception MyError as err:
    my_logger.exception("Error occured")
    raise MyProcessError("Process failed") from err
跟踪日志中提到的更改是将“在处理上述异常期间,发生了另一个异常”替换为“上述异常是以下异常的直接原因”

那么使用这种语法的原因是什么?我应该在什么时候将其包含到代码中?
示例很受欢迎:-)

在异常处理程序中,如果显式引发异常,您可能希望从err使用
,或者从None
使用
(取决于抑制原始回溯是否更有意义)

如果没有来自
,您会收到一条消息:“在处理上述异常期间,发生了另一个异常”,提示“出现了一些错误,然后,在尝试从中恢复时,出现了一些其他错误(可能是无关的)。例如,当您输入错误(
my_logger.expeption(“错误发生”)
)或者您试图将某些内容保存到无法打开的文件中

使用
中的
,它表明只有一件事出错,即您没有处理自己的问题,但您有一些对程序员或用户有用的更多信息。例如,您可以捕获一个
键错误
,并引发另一个异常,消息为“试图编辑一个不存在的小部件”或其他任何内容


因此,
raisesomeexception(“somedescription”)from err
是一种能够解释当错误发生时,如果引发
err
的代码不能这样做(因为它来自标准库,或者因为它缺少调用它的必要上下文)会发生什么的方法在异常处理程序中,如果显式引发异常,您将希望从err使用
,或者从None使用
(取决于抑制原始回溯是否更有意义)

如果没有来自
,您会收到一条消息:“在处理上述异常的过程中,发生了另一个异常”,提示“出现了问题,然后,在尝试从中恢复时,出现了其他问题(可能无关)。例如,当您输入错误(
my_logger.expption(“出错”)
)或试图将某些内容保存到无法打开的文件时,就会出现这种情况

使用
中的
,它表明只有一件事出了问题,即您没有处理自己的问题,但您有一些对程序员或用户有用的更多信息。例如,您可以捕获一个
KeyError
并引发另一个异常,消息为“试图编辑一个不存在的小部件”或其他任何内容


因此,
raisesomeexception(“somedescription”)from err
是一种能够解释当错误发生时,如果引发
err
的代码不能做到这一点(因为它来自标准库,或者因为它缺少调用它的必要上下文)会发生什么的方法,在没有用户的情况下,这两个独立的事件会紧接着发生错误。

语句
从原因引发异常
相当于:

exc = EXCEPTION
exc.__cause__ = CAUSE
raise exc
此功能有时可用于存储有关异常链的信息,以便在最后一级进行处理、传输或记录

例如,在创建自己的库时,我们使用基类创建自己的异常层次结构,并且我们不希望从函数中抛出第三个库的异常。但同时,我们希望将有关原始异常的信息保存为详细信息


class ThirdPartyLibException(Exception):
    pass


def third_party_lib_foo():
    ...
    raise ThirdPartyLibException('third party exception')

语句
从原因引发异常
相当于:

exc = EXCEPTION
exc.__cause__ = CAUSE
raise exc
此功能有时可用于存储有关异常链的信息,以便在最后一级进行处理、传输或记录

例如,在创建自己的库时,我们使用基类创建自己的异常层次结构,并且我们不希望从函数中抛出第三个库的异常。但同时,我们希望将有关原始异常的信息保存为详细信息


class ThirdPartyLibException(Exception):
    pass


def third_party_lib_foo():
    ...
    raise ThirdPartyLibException('third party exception')

如果新异常确实是一个新问题,则偶尔有理由在异常处理程序中引发异常,而不使用来自
。例如,如果您正在处理
所有的IsBurningError
,并且没有灭火器,您将
在没有来自
的情况下引发无灭火器错误。(然后捕获异常的代码在没有意识到有火要扑灭的情况下替换了灭火器,因为它没有检查
\uuuuuuuuuuuuuuu
,软件设计也没有真正提出一个处理多个异常的好范例。
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu原因
比Pytho更好。)N2处理了它,但仍有很多需要改进的地方。)如果新异常确实是一个新问题,那么偶尔会有理由在异常处理程序中引发异常而不使用
from
。例如,如果您正在处理
EverythingIsBurningError
,并且没有灭火器,那么您将
在不使用
from
的情况下引发nofireerightererror
。(然后捕获异常的代码在没有意识到有火要扑灭的情况下替换了灭火器,因为它没有检查
\uuuuuuuuuuuuuuu
,软件设计也没有真正提出一个处理多个异常的好范例。
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu原因
比Pytho更好。)N2处理了它,但仍有很多需要改进的地方。)