说明
《Python 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gairuo123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
在 Python 中,raise语句用于引发异常(exception)。异常是程序运行时发生的错误或异常情况的信号。raise 语句用于在程序执行过程中显式地引发异常。异常是指在程序执行过程中遇到的错误或不正常情况,它打断了正常的程序流程。通过raise语句,程序员可以在代码中指定在某些条件下引发异常,从而使程序更加健壮,能够更好地处理错误情况。
如果x不是整数,则引发 TypeError:
x = "hello"
if not type(x) is int:
raise TypeError("Only integers are allowed")
raise 抛出的必须是一个异常:
raise 123
# TypeError: exceptions must derive from BaseException
无缘无故抛出一个异常:
raise BaseException('我错了')
引发内置异常:
raise ValueError("这是一个值错误")
引发自定义异常:
# 定义一个自定义异常类
class CustomError(Exception):
pass
# 引发自定义异常
raise CustomError("这是一个自定义异常")
引发异常并附带追踪信息:
try:
# 一些可能引发异常的代码
x = 1 / 0
except ZeroDivisionError as e:
# 在捕获到异常后,使用raise重新引发异常,并附带自定义的描述和追踪信息
raise ValueError("发生除零错误") from e
在这个例子中,首先尝试执行可能引发异常的代码(这里是除零错误)。如果发生了ZeroDivisionError异常,通过raise语句重新引发了一个ValueError异常,并使用from关键字将原始异常(除零错误)作为新异常的原因,从而提供了追踪信息。
raise 语句通常与 try 和 except 语句一起使用,以在发生异常时捕获并处理异常。
在 Python 中,raise ... from ...
语法用于在引发异常时同时提供原始异常的上下文信息。这是一种异常链(exception chaining)的方式,允许开发者在捕获到一个异常后,通过 raise ... from ...
语法将原始异常连接到当前异常中,以提供更详细的错误追踪信息。
具体语法如下:
try:
# 一些可能引发异常的代码
...
except SomeException as e:
# 在捕获到异常后,使用 raise ... from ... 提供上下文信息
raise AnotherException("描述信息") from e
这里的 SomeException 是在 try 块中可能引发的异常,而 AnotherException 是你想要引发的新异常,同时通过 from 关键字将原始异常(SomeException)链接到新异常的上下文中。
使用 raise ... from ... 的好处在于,它能够帮助调试者更清晰地了解异常是如何传播的,从而更容易定位问题所在。当你查看异常追踪信息时,可以看到整个异常链,了解异常的起源。
以下是一个示例:
try:
x = 1 / 0
except ZeroDivisionError as e:
raise ValueError("发生除零错误") from e
在这个例子中,如果发生了除零错误,将会引发一个新的 ValueError 异常,并将原始的 ZeroDivisionError 作为上下文信息链接到新异常中。这样,在查看异常追踪信息时,可以清晰地看到异常的传播路径。
总体而言,raise ... from ...
是一种提供异常上下文信息的强大方式,帮助开发者更好地理解和调试程序中的异常。
raise语句的一般语法如下:
raise_stmt ::= "raise" [expression ["from" expression]]
如果没有提供表达式,则 raise 会重新引发当前正在处理的异常,它也被称为 活动的异常。 如果当前没有活动的异常,则会引发 RuntimeError 来提示发生了错误。
否则的话,raise 会将第一个表达式求值为异常对象。 它必须为 BaseException 的子类或实例。 如果它是一个类,当需要时会通过不带参数地实例化该类来获得异常的实例。
异常的 类型 为异常实例的类,值 为实例本身。
当有异常被引发时通常会自动创建一个回溯对象并将其关联到它的 __traceback__
属性。 你可以创建一个异常并使用 with_traceback() 异常方法直接设置你的回溯对象(该方法将返回同一异常实例,并将回溯对象设为其参数),就像这样:
raise Exception("foo occurred").with_traceback(tracebackobj)
from 子句用于异常串连:如果给出该子句,则第二个 表达式 必须为另一个异常类或实例。 如果第二个表达式是一个异常实例,它将作为 __cause__
属性(为一个可写属性)被关联到所引发的异常。 如果该表达式是一个异常类,这个类将被实例化且所生成的异常实例将作为 __cause__
属性被关联到所引发的异常。 如果所引发的异常未被处理,则两个异常都将被打印:
try:
print(1 / 0)
except Exception as exc:
raise RuntimeError("Something bad happened") from exc
'''
---------------------------------------------------------------------------
ZeroDivisionError Traceback (most recent call last)
Cell In[5], line 2
1 try:
----> 2 print(1 / 0)
3 except Exception as exc:
ZeroDivisionError: division by zero
The above exception was the direct cause of the following exception:
RuntimeError Traceback (most recent call last)
Cell In[5], line 4
2 print(1 / 0)
3 except Exception as exc:
----> 4 raise RuntimeError("Something bad happened") from exc
RuntimeError: Something bad happened
'''
当已经有一个异常在处理时如果有新的异常被引发则类似的机制会隐式地起作用。 异常可以通过使用 except 或 finally 子句或者 with 语句来处理。 之前的异常将被关联至新异常的 __context__
属性:
try:
print(1 / 0)
except:
raise RuntimeError("Something bad happened")
'''
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
print(1 / 0)
~~^~~
ZeroDivisionError: division by zero
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
raise RuntimeError("Something bad happened")
RuntimeError: Something bad happened
'''
异常串连可通过在 from 子句中指定 None 来显式地加以抑制:
try:
print(1 / 0)
except:
raise RuntimeError("Something bad happened") from None
'''
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
RuntimeError: Something bad happened
'''
有关异常的更多信息可在 异常 一节查看,有关处理异常的信息可在 try 语句 一节查看。
在 3.3 版更改: None 现在允许被用作 raise X from Y
中的 Y。
3.3 新版功能: 使用 __suppress_context__
属性来抑制异常上下文的自动显示。
在 3.11 版更改: 如果活动异常的回溯在 except 子句中被修改,则会有后续的 raise 语句重新引发该异常并附带被修改的回溯。 在之前版本中,重新引发该异常则会附带它被捕获时的回溯。
更新时间:2023-12-22 15:15:02 标签:python raise 异常