0Pricing
Python Academy · 课时

引发与重新引发异常

使用 raise 发出错误信号,并使用重新引发来传播异常。

引发与重新引发异常 是 CoddyKit 上的免费 Python Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Python Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Python Academy 课程共包含 4 节课。

介绍

raise 关键字可以让您显式发出错误信号。重新引发异常会保留原始错误上下文。

引发内置异常

raise ValueError('message') 会立即引发指定的异常类型,并附带给定消息。
def divide(a, b):
    if b == 0:
        raise ValueError('Denominator cannot be zero')
    return a / b
try:
    divide(5, 0)
except ValueError as e:
    print(e)

再次引发同一异常

在 except 中,raise(不带参数)会重新引发当前异常,并保留原始回溯信息。
def process(data):
    try:
        return int(data)
    except ValueError:
        print('logging error')
        raise  # re-raises original
try:
    process('abc')
except ValueError:
    print('caller caught it')

使用 from 链接异常

raise NewError('msg') from original 会链接两个异常,并设置 exc.__cause__。
try:
    int('abc')
except ValueError as original:
    raise RuntimeError('processing failed') from original

抑制异常链

raise NewError() from None 会断开异常链,原始异常会在回溯信息中被隐藏。
try:
    int('abc')
except ValueError:
    raise RuntimeError('clean error') from None

assert 语句

如果 condition 为 False,assert condition, 'message' 会引发 AssertionError。它只适合在开发期间检查不变量。
def sqrt(x):
    assert x >= 0, f'Input must be non-negative, got {x}'
    return x ** 0.5
try:
    sqrt(-1)
except AssertionError as e:
    print(e)

条件式引发异常

在函数开头使用带有 raise 的守卫子句,可以明确前置条件并避免深层嵌套。
def process(items):
    if not items:
        raise ValueError('items must not be empty')
    return items[0]
print(process([1, 2, 3]))

重新引发与新建异常

重新引发异常(裸 raise)会保留上下文。新异常会隐藏上下文。请使用异常链来同时保留两者。
def outer():
    try:
        inner()
    except ValueError as e:
        raise RuntimeError('outer failed') from e
def inner():
    raise ValueError('inner failed')
try:
    outer()
except RuntimeError as e:
    print(e, e.__cause__)

finally 中的异常

在 finally 中引发异常会替换原始异常。除非绝对必要,否则请避免在 finally 中引发异常。
try:
    try:
        raise ValueError('original')
    finally:
        print('finally ran')
except ValueError as e:
    print('caught:', e)

warnings.warn 与 raise

对于可恢复的非致命错误,请使用 warn();对于必须处理的错误,请使用 raise。它们的用途不同。
import warnings
def old_func():
    warnings.warn('Deprecated', DeprecationWarning)
    return 42
print(old_func())

raise from None 模式

将库异常包装为您自己的接口异常时,请使用 from None,以避免泄露内部细节。
class DBError(Exception): pass
def query(q):
    try:
        raise ConnectionError('refused')
    except ConnectionError:
        raise DBError('query failed') from None
try:
    query('SELECT 1')
except DBError as e:
    print(e)

快速检查

在 except 代码块中,raise(不带参数)会做什么?

回顾

raise Type('msg') 会发出错误信号。裸 raise 会重新引发异常。raise New from Old 会链接异常。raise New from None 会抑制上下文。使用 assert 检查开发期间的不变量。

继续学习

做得很好!请继续下一课,持续进步。

常见问题解答

「引发与重新引发异常」课时是免费的吗?

是的 — 「引发与重新引发异常」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Python Academy 课程的其余内容,请升级到 CoddyKit PRO。 Python Academy 课程共包含 4 节课。

「引发与重新引发异常」这节课中我会学到什么?

使用 raise 发出错误信号,并使用重新引发来传播异常。 你通过在浏览器中直接运行的动手代码来练习 Python Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Python Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Python Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。

「引发与重新引发异常」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Python Academy 课中编写并运行代码吗?

能。每节 Python Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 理解异常
  2. try / except / else / finally
  3. 引发与重新引发异常
  4. 自定义异常类
← 返回 Python Academy