當前位置:
首頁 > 知識 > Python 的 except 怪癖

Python 的 except 怪癖

(此處已添加圈子卡片,請到今日頭條客戶端查看)

讓我來展示一下我最喜歡的 Python 怪癖。你希望這段 Python 代碼做什麼?

Python 的 except 怪癖

如果你是從另一種編程語言過來學習 Python 的,你可能希望except子句引入嵌套範圍,因此在子句中賦值給 e 不會影響外部作用域中已有的 e 變數。然而,在 Python 中,控制結構通常不引入嵌套作用域(列表推導是一個例外),所以如果你有更多的 Python 經驗,你可能會期望它列印一個ZeroDivisionError實例。

實際上,在標準 CPython 實現中,它什麼也不列印;同時,最後一行將引發一個NameError。這是一個 bug 嗎?事實上,這是故意的。如果查看 except 子句生成的位元組碼,可以看到:

Python 的 except 怪癖

當控制流退出except塊時,Python 將從作用域中刪除該名稱。為什麼?因為異常持有對當前棧幀的引用,該棧幀包含作用域內的所有內容。由於Python主要是通過引用計數來管理內存主體的,這意味著當前作用域內的任何內容都不會被釋放,直到下一輪垃圾收集運行 (如果有的話)。目前的行為是內存使用、易於實現和語言整潔之間的折衷。它有點缺點,但我認為它體現了我喜歡Python的一點:不讓純粹性妨礙實用性。

但這隻解釋了DELETE_NAME指令。為什麼 CPython 把e設為None,即便隨後立即就刪除了這個變數?好吧,設想你和 CPython 團隊有相同的想法,並且決定在 except 塊的末尾清理異常引用:

Python 的 except 怪癖

在except塊的末尾,CPython 將嘗試刪除你已經刪除的名字e!為了解決這個問題,CPython 在刪除e之前賦值e = None,以確保e存在。


英文原文:https://pydist.com/blog/python-except

譯者:青書

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 Python部落 的精彩文章:

在瀏覽器中用Python做數據科學:Pyodide
Django快速入門

TAG:Python部落 |