從 Python 3.14 起,在 finally 區塊中使用 return、break 或 continue 將會觸發警告喔!
對還不太熟悉 try...except...finally
的朋友來說,看到下面這段程式碼可能會有些困惑:
def div(n, m):
try:
return n / m
finally:
return 0
請問:div(1, 2)
的回傳值會是什麼?
答案是:0
這是因為 finally
區塊的特性是「無論如何都會被執行」,所以即使 try
區塊裡的 return n / m
原本會回傳 0.5,最終仍被 finally
的 return 0
覆蓋掉。
更令人意外的是,就算執行 div(1, 0)
,也不會出現任何錯誤!因為 finally
的 return
把原本應該拋出的 ZeroDivisionError 給吃掉了。
這行為其實有明確記載在 Python 官方文件中:
If the finally clause executes a break, continue or return statement, exceptions are not re-raised.
If a finally clause includes a return statement, the returned value will be the one from the finally clause’s return statement, not the value from the try clause’s return statement.
這個行為很違反開發者的直覺,也可能帶來難以察覺的 bug。
因此,PEP 765 提議從 Python 3.14 開始,先對這類用法發出 SyntaxWarning
,之後的版本則計畫直接視為語法錯誤(SyntaxError
)。
換句話說,從現在開始,無論你使用的是哪個版本的 Python,只要未來有升級計畫,都應該避免在 finally
中使用 return
、break
或 continue
囉!