用抛出异常替代返回错误会拥有更稳定的返回值类型,它永远只会返回 Item 类型或是抛 出异常。

在处理异常时:

  1. 使用异常比返回错误码更稳定

    • create_item(name) 只会有两种情况:成功返回 Item抛出异常 ,不会返回错误码、None 或其他类型数据,这样可以减少调用者的判断逻辑。
  2. 异常会自动向上传播,提供了灵活性

    • 直接调用 create_item() 的地方可以选择不处理 CreateItemError,让异常继续上传,交给更高层的代码去处理,比如 UI 层或日志系统。
    • 这样避免了在每个调用处都写一堆 if/else 代码,提高了可读性。
  3. 但如果缺少统一异常处理,可能导致程序崩溃

    • 如果 CreateItemError 没有被任何地方捕获,它会一直向上传播,直到顶层,最终可能导致程序崩溃。

    • 解决方案是在主函数或入口点 设置全局异常处理 ,例如:

      python 复制代码
      try:
          create_from_input()
      except CreateItemError as e:
          print(f"Unhandled CreateItemError: {e}")
      except Exception as e:
          print(f"Unexpected error: {e}")

为什么这样设计更合理?

1. 对比返回错误码

传统返回错误码的方式

python 复制代码
def create_item(name):
    if len(name) > MAX_LENGTH_OF_NAME:
        return None, 'name too long'
    if len(get_current_items()) > MAX_ITEMS_QUOTA:
        return None, 'quota exceeded'
    return Item(name=name), ''

item, err = create_item(name)
if err:
    print(f"Create item failed: {err}")
else:
    print(f"Item {name} created")
  • 问题
    • 需要判断 err,增加了调用方的额外工作。
    • 调用方可能忘记检查 err,导致程序异常行为。
    • 如果返回值结构变了(比如从 (Item, str) 变成 (Item, int)),调用方可能要改很多代码。
2. 使用异常的方式
python 复制代码
def create_item(name):
    if len(name) > MAX_LENGTH_OF_NAME:
        raise CreateItemError('name too long')
    if len(get_current_items()) > MAX_ITEMS_QUOTA:
        raise CreateItemError('quota exceeded')
    return Item(name=name)

try:
    item = create_item(name)
    print(f"Item {name} created")
except CreateItemError as e:
    print(f"Create item failed: {e}")
  • 优点
    • create_item() 只返回 Item 或抛出异常,调用方只用关注成功的情况,不需要额外判断错误码。
    • 代码更清晰,减少 if/else 嵌套。
    • 可以在更高层统一处理 CreateItemError,提高代码的可维护性。

总结

异常让函数返回值更稳定 ,不需要额外处理错误码。

异常自动向上传播,让调用方可以自由选择是否处理

但必须确保顶层有统一的异常处理,否则可能导致程序崩溃。

最佳实践:使用异常可以提高代码的可读性和可维护性,但一定要在系统入口处做好全局异常处理,防止程序意外崩溃。


create_item() 方法中如果执行了raise抛出异常,还会往后执行 return Item(name=name)么?

不会!

一旦 raise 语句被执行,函数会立即中断 ,不会继续执行后续代码。因此,如果 raise CreateItemError(...) 被触发,return Item(name=name) 永远不会执行


示例代码

python 复制代码
def create_item(name):
    if len(name) > 10:
        raise ValueError("name too long")
    print("This line will be executed if no exception occurs.")
    return f"Item({name})"

# 测试
try:
    create_item("short_name")  # 正常情况
    create_item("this_name_is_too_long")  # 触发异常
except ValueError as e:
    print(f"Caught exception: {e}")

运行结果

复制代码
This line will be executed if no exception occurs.
Caught exception: name too long

说明

  1. 第一次调用 create_item("short_name"),没有触发异常,所以 print 语句执行了,return 也执行了。
  2. 第二次调用 create_item("this_name_is_too_long"),触发了 raise ValueError("name too long"),函数立即终止,return 语句不会执行

总结

  • raise 语句会立即终止函数的执行,抛出异常给调用者。
  • 如果 raise 被执行,后面的 return 语句就不会执行
  • 异常会向上传播,直到被 try-except 代码块捕获,否则程序会崩溃
相关推荐
ytadpole7 分钟前
揭秘设计模式:命令模式-告别混乱,打造优雅可扩展的代码
java·设计模式
sinat_6020353610 分钟前
模块与包的导入
运维·服务器·开发语言·python
计算机学姐10 分钟前
基于Python的旅游数据分析可视化系统【2026最新】
vue.js·后端·python·数据分析·django·flask·旅游
恋雨QAQ11 分钟前
python函数和面向对象
开发语言·python
用户37215742613512 分钟前
Java 教程:轻松实现 Excel 与 CSV 互转 (含批量转换)
java
天雪浪子30 分钟前
Python入门教程之逻辑运算符
开发语言·python
叫我阿柒啊40 分钟前
Java全栈开发实战:从基础到微服务的深度解析
java·微服务·kafka·vue3·springboot·jwt·前端开发
张子夜 iiii1 小时前
实战项目-----在图片 hua.png 中,用红色画出花的外部轮廓,用绿色画出其简化轮廓(ε=周长×0.005),并在同一窗口显示
人工智能·pytorch·python·opencv·计算机视觉
凯尔萨厮1 小时前
Java学习笔记三(封装)
java·笔记·学习
霸道流氓气质1 小时前
Java开发中常用CollectionUtils方式,以及Spring中CollectionUtils常用方法示例
java·spring