Skip to main content
Documents
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

Try

🟦 1. 基本结构

try:
    ...
except ExceptionType:
    ...
else:
    ...
finally:
    ...

作用:

  • try:执行可能出错的代码
  • except:捕获异常并处理
  • else:try 无异常时执行(少用,但非常有用)
  • finally:无论是否异常都执行(常用于释放资源)

🟩 2. 最常见的 try-except

try:
    result = 10 / 0
except ZeroDivisionError:
    print("不能除以 0")

🟦 3. 捕获多种异常

try:
    ...
except (KeyError, ValueError, TypeError):
    ...

🟩 4. 捕获所有异常(工程中常用,但必须谨慎)

try:
    ...
except Exception as e:
    logger.exception(e)

适用:

  • API 服务端
  • 爆炸范围较大的任务
  • 守护程序
  • 数据同步

不适合:

  • 小范围逻辑,导致隐藏 bug

🟦 5. 获取异常对象

except Exception as e:
    print(type(e), e)

🟩 6. 使用 else(非常 Pythonic,但容易忽略)

try:
    data = fetch()
except Exception:
    log("失败")
else:
    log("成功,执行后置逻辑")

优势:

  • try 只包含真正可能报错的语句
  • 其他逻辑写到 else,代码更干净

🟦 7. 使用 finally 做清理(强烈推荐熟练掌握)

try:
    conn = connect()
    ...
finally:
    conn.close()

finally 永远执行,即使:

  • return
  • break
  • continue
  • exception
  • sys.exit()

都无效,finally 都会执行。

🟩 8. try-except-finally 的全结构例子

try:
    x = risky()
except ValueError:
    print("值错误")
else:
    print("没有异常")
finally:
    print("一定执行")

🟦 9. 自定义抛异常

if not isinstance(x, int):
    raise TypeError("x 必须是 int")

你项目中建议对所有输入进行严格类型检查。

🟩 10. try + loguru(你项目会用到)

try:
    db.save(data)
except Exception as e:
    logger.exception(f"保存失败: {e}")

loguru 会同时打印堆栈,非常清晰。

🟦 11. 常见坑:except 后面漏写 Exception

错误:

except:
    pass

严重问题:

  • 把系统退出、KeyboardInterrupt 都吃掉
  • 导致调试困难
  • 隐藏 bug

正确:

except Exception:
    pass

或者更推荐:

except Exception as e:
    logger.error(e)

🟩 12. try 在实际项目中的优雅使用方式

① API 调用(你项目爬取 cls / stock / news 时常用)

def fetch(url):
    try:
        resp = requests.get(url, timeout=10)
        resp.raise_for_status()
        return resp.json()
    except Exception as e:
        logger.exception(f"请求失败: {url}")
        return None

② 数据库事务(非常重要)

try:
    with Session(engine) as session:
        session.add(obj)
        session.commit()
except Exception:
    session.rollback()
    raise

你的项目的 DatabaseObject 类已经有类似逻辑。

③ FastAPI 中间件捕获异常

@app.exception_handler(Exception)
async def global_exception_handler(request, exc):
    logger.exception(exc)
    return JSONResponse(status_code=500, content={"message": "server error"})

④ 循环重试 + try

for _ in range(3):
    try:
        return risky_operation()
    except Exception:
        time.sleep(1)

你项目常写的 utils.retry() 就是这样。

🟦 13. 进阶:try 与上下文管理器配合(with)

代替:

try:
    f = open("a.txt")
    data = f.read()
finally:
    f.close()

使用 with:

with open("a.txt") as f:
    data = f.read()

更清晰。

🟩 14. try 最佳实践(从《Effective Python》总结)

1. 尽量缩小 try 范围

避免吞掉太多逻辑。

2. 仅捕获你能处理的异常

不要用空 except。

3. 用 finally 做资源释放

适用于 I/O、db、锁、网络流。

4. 对于流程控制,用异常比 if 更简洁

例如停止迭代。

5. 写库或框架时,永远不要吃掉所有异常

应该重新 raise 或记录日志。

🟦 15. 最后:最常用模板(收藏)

安全执行带日志

try:
    ...
except Exception as e:
    logger.exception(e)

带事务的语句

try:
    ...
    commit()
except:
    rollback()
    raise

重试机制

for _ in range(3):
    try:
        return work()
    except:
        time.sleep(1)

完整结构

try:
    ...
except Exception:
    ...
else:
    ...
finally:
    ...