漲姿勢(shì)了,raise...from... 是個(gè)什么操作?
點(diǎn)擊上方Python知識(shí)圈,設(shè)為星標(biāo)
回復(fù)1024獲取Python資料

作者:weapon
原文:https://zhuanlan.zhihu.com/p/52091476
閱讀文本大概需要 2?分鐘
點(diǎn)擊「閱讀原文」查看pk哥原創(chuàng)精品視頻。
1. 問(wèn)題現(xiàn)象
Python 的?raise?和?raise from?之間的區(qū)別是什么?
try:
????print(1?/?0)
except?Exception?as?exc:
????raise?RuntimeError("Something?bad?happened")
輸出:
Traceback?(most?recent?call?last):
??File?"test4.py",?line?2,?in?
????print(1?/?0)
ZeroDivisionError:?division?by?zero
During?handling?of?the?above?exception,?another?exception?occurred:
Traceback?(most?recent?call?last):
??File?"test4.py",?line?4,?in?
????raise?RuntimeError("Something?bad?happened")
RuntimeError:?Something?bad?happened
而?raise from?:
try:
????print(1?/?0)
except?Exception?as?exc:
????raise?RuntimeError("Something?bad?happened")?from?exc
輸出:
Traceback?(most?recent?call?last):
??File?"test4.py",?line?2,?in?
????print(1?/?0)
ZeroDivisionError:?division?by?zero
The?above?exception?was?the?direct?cause?of?the?following?exception:
Traceback?(most?recent?call?last):
??File?"test4.py",?line?4,?in?
????raise?RuntimeError("Something?bad?happened")?from?exc
RuntimeError:?Something?bad?happened
2. 問(wèn)題分析
不同之處在于,from?會(huì)為異常對(duì)象設(shè)置?__cause__?屬性表明異常的是由誰(shuí)直接引起的。
處理異常時(shí)發(fā)生了新的異常,在不使用?from?時(shí)更傾向于新異常與正在處理的異常沒(méi)有關(guān)系。而?from?則是能指出新異常是因舊異常直接引起的。這樣的異常之間的關(guān)聯(lián)有助于后續(xù)對(duì)異常的分析和排查。from?語(yǔ)法會(huì)有個(gè)限制,就是第二個(gè)表達(dá)式必須是另一個(gè)異常類(lèi)或?qū)嵗?/p>
如果在異常處理程序或 finally 塊中引發(fā)異常,默認(rèn)情況下,異常機(jī)制會(huì)隱式工作會(huì)將先前的異常附加為新異常的?__context__屬性。
當(dāng)然,也可以通過(guò)with_traceback()方法為異常設(shè)置上下文__context__屬性,這也能在traceback更好的顯示異常信息。
raise?Exception("foo?occurred").with_traceback(tracebackobj)
3. 禁止異常關(guān)聯(lián)
from 還有個(gè)特別的用法:raise ... from None?,它通過(guò)設(shè)置?__suppress_context__?屬性指定來(lái)明確禁止異常關(guān)聯(lián):
try:
????print(1?/?0)
except?Exception?as?exc:
????raise?RuntimeError("Something?bad?happened")?from?None
輸出:
Traceback?(most?recent?call?last):
??File?"test4.py",?line?4,?in?
????raise?RuntimeError("Something?bad?happened")?from?None
RuntimeError:?Something?bad?happened
4. 總結(jié)一下
在異常處理程序或?finally?塊中引發(fā)異常,Python 會(huì)為異常設(shè)置上下文,可以手動(dòng)通過(guò)?with_traceback()?設(shè)置其上下文,或者通過(guò)?from?來(lái)指定異常因誰(shuí)引起的。這些手段都是為了得到更友好的異常回溯信息,打印清晰的異常上下文。若要忽略上下文,則可以通過(guò)?raise ... from None?來(lái)禁止自動(dòng)顯示異常上下文。

-----------------------公眾號(hào):Python知識(shí)圈博客:www.pyzhishiquan.com知乎:Python知識(shí)圈微信視頻號(hào):菜鳥(niǎo)程序員 (分享有趣的編程技巧、Python技巧)bilibili:菜鳥(niǎo)程序員的日常(目前原創(chuàng)視頻:16,累計(jì)播放量:55萬(wàn))
一個(gè)學(xué)習(xí)Python的人,喜歡分享,喜歡搞事情!
長(zhǎng)按下圖二維碼關(guān)注,和你一起領(lǐng)悟Python的魅力。
Python知識(shí)圈公眾號(hào)的交流群已經(jīng)建立,群里可以領(lǐng)取 Python 和人工智能學(xué)習(xí)資料,大家可以一起學(xué)習(xí)交流,效率更高,如果是想發(fā)推文、廣告、砍價(jià)小程序的敬請(qǐng)繞道!一定記得備注「交流學(xué)習(xí)」,我會(huì)盡快通過(guò)好友申請(qǐng)哦!通過(guò)好友后私聊我「學(xué)習(xí)資料」或者「進(jìn)群」都可以。
掃碼添加,備注:交流學(xué)習(xí)
往期推薦010203
打基礎(chǔ)一定要吃透這12類(lèi) Python 內(nèi)置函數(shù)

