else仅在try无异常时执行,用于放置依赖成功结果的后续操作;它可访问try中已成功赋值的变量,不捕获异常,与finally正交,执行顺序为try→(else)→finally。

Try-Except-Else 的执行顺序到底是什么
Python 的 else 子句在 try 块中**没有抛出任何异常**时才执行,且它不会捕获 try 中的异常——异常仍由 except 处理。关键点是:else 不是“兜底逻辑”,而是“成功路径专属逻辑”,且它比把代码写在 try 末尾更安全。
为什么不能把成功逻辑直接塞进 try 末尾
常见错误是把本该放在 else 的代码硬塞进 try,结果导致本不该被捕捉的异常也被吞掉。比如:
try:
data = json.loads(response_text)
process(data) # ← 如果 process() 抛 ValueError,也会被 except 捕获!
except json.JSONDecodeError:
log_error("invalid JSON")
这会让业务层错误(如 process() 内部空指针)和解析错误混为一谈,掩盖真实问题。正确做法是:
-
try只放可能抛出预期异常的语句(如json.loads()) -
else放依赖前一步成功的后续操作(如process(data)) -
except专注处理try中定义的那类异常
Else 中能访问 try 里定义的变量吗
可以,但前提是这些变量在 try 中**已成功赋值**。如果 try 在赋值前就异常了,变量名甚至不存在,else 会触发 NameError。
例如:
try:
user = get_user_by_id(user_id) # ← 若这里抛异常,user 未定义
profile = user.get_profile() # ← 若这里抛异常,profile 未定义
except UserNotFoundError:
handle_missing()
else:
send_notification(profile) # ← 安全:只有 user 和 profile 都成功创建后才执行
注意:else 无法访问 try 中「可能未完成赋值」的中间变量;若逻辑链长,建议拆成多个 try-except-else 或用显式标志位。
Finally 会干扰 else 吗
不会。finally 总是执行,但它和 else 是正交关系:else 关注“是否成功”,finally 关注“是否必须收尾”。三者共存时顺序是:try → (else) → finally(括号表示仅当无异常时进入 else)。
典型场景是资源清理 + 成功后提交:
conn = open_db_connection()
try:
result = conn.execute(query)
except DatabaseError as e:
rollback_transaction()
else:
commit_transaction() # ← 仅当 execute 成功才提交
finally:
conn.close() # ← 无论成败都关闭连接
容易忽略的是:else 中的异常不会触发 except,但会跳过 finally 后的后续代码——所以关键清理动作一定要放进 finally,别指望 else 自带兜底。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











