從JavaScript到Python之異常

不少前端工程師看到這個標(biāo)題可能會產(chǎn)生質(zhì)問:

我js用得好好的,能后端能APP,為什么還要學(xué)習(xí)Python?

至少有下面兩個理由:

  1. 學(xué)習(xí)曲線。ES6之后的JavaScript(TypeScript)的在語法上和Python有很多異曲同工的地方,所以學(xué)習(xí)曲線非常平滑,上手難度很低。
  2. 應(yīng)用場景。JavaScript雖然是web開發(fā)的王者,但是其在某些方面還是存在一些問題的。比如Node.js雖然可以寫后端,但大多用于CGI層,做接口整合和模板渲染,而Python、Java這類語言已被廣泛應(yīng)用于后端服務(wù)編寫,同時Python在做機(jī)器學(xué)習(xí)等方面也很有優(yōu)勢。

這篇文章我們通過對比兩種語言之間的“異?!眮韺W(xué)習(xí)Python。

為什么需要對異常進(jìn)行處理

異常是編寫代碼時必須考慮的問題,但卻并不是一個熱門話題,少有文章提到。
尤其在web前端這一塊,瀏覽器的強(qiáng)大容錯能力幫工程師解決(隱藏)了大量的異常。
但如果忽視異常輕則影響功能運(yùn)行,重則導(dǎo)致系統(tǒng)崩潰,造成經(jīng)濟(jì)損失。

異常處理

捕獲

JavaScript 異常捕獲關(guān)鍵字與 Python 一致,都是使用try

// JavaScript
try {
  ...
}
# Python
try:
  ...

但是兩者都具有局限性:只能用來捕獲同步執(zhí)行代碼的異常。

對于異步代碼的異常捕獲的情況 JavaScript 處理起來相對復(fù)雜,按運(yùn)行環(huán)境就可以分為 Node.js 和 瀏覽器,按捕獲范圍又可以分為全部捕獲和局部捕獲。

// 瀏覽器全局異常捕獲
window.onError = e => {}  
window.addEventListener('', e => {}) 捕獲請求錯誤
// 瀏覽器Ajax異常捕獲
var xhr = new XMLHttpRequest();
xhr.onload = function(e) { 
  if(this.status > 400){
    ...
  }
};
// Node.js 全局異常捕獲
process.on('uncaughtException', e => {})
// Node.js 回調(diào)方式異常捕獲
fs.readFile('/etc/passwd', (err, data) => {
  if (err) {
    ...
  }
});

Python 的情況要簡單很多,即使使用異步線程或進(jìn)程,也可以在函數(shù)內(nèi)部進(jìn)行捕獲,然后其它方式上報。

def _parse_speed(key_name, speed_list):
  try:
    ...

t = threading.Thread(target=_parse_speed, args=(v, speed_list))
t.start()

由于異常捕獲情況比較復(fù)雜,如無特殊說明,后文討論僅指使用try關(guān)鍵字的同步異常捕獲。

處理

再看看JavaScript幾種處理異常方式。

  • catch。catch 語句塊用來處理異常,處理方式也相當(dāng)粗放,try 語句塊內(nèi)的所有異常都會被捕獲。
  • finally。finally 語句塊表示無論是否發(fā)生異常,語句塊代碼一定會被執(zhí)行。

不少讀者可能會以為在catch語句塊后執(zhí)行的代碼和finally語句塊作用一樣,但其實是有區(qū)別的!

下面舉個例子

fn = () => {
  try {
    throw Error()
  } catch(e) {
    throw Error()
    return 1
  } finally {
    return 2
  }
  return 3
}
fn() // 是2不是3

也就是說 finally 語句塊中的代碼,不論 try 還是 catch 執(zhí)行出錯都會執(zhí)行。

Python的異常處理:

  • except??梢灾付ㄐ枰幚淼亩鄠€異常類型,可以有多個異常處理邏輯,寫法非常靈活。
  • else。else 語句塊可以當(dāng) try 語句塊未發(fā)生異常時執(zhí)行。
  • finally。特性同 JavaScript。

下面列舉使用 except 的幾個例子:

# 捕獲異常實例
except Exception as e:

# 批量異常捕獲
except (IOError, TypeError):

# 異常分類捕獲:
except OSError as err:
  ...
except ValueError:
  ...
except:
  ...

拋出

JavaScript 中可以通過關(guān)鍵字 throw 來拋出一個 Error 對象。
Python中與之對應(yīng)的是 raise ,用來拋出一個 Exception 實例。

雖然關(guān)鍵字不一樣但是寫法基本相似:

// JavaScript
throw Error(...)
# Python
raise Exception(...)

異常類型

對于 JavaScript 而言,談異常類的意義不大,處理不同的異常需要手動判斷,所以異常類型也比較簡單。

js-error.jpg

Python的異常類型則豐富得多


py-error.jpg

總結(jié)

  • 捕獲方面,JavaScript 的場景要比 Python 復(fù)雜,遷移學(xué)習(xí) Python 很簡單。
  • 處理方面,兩者都支持 finally 關(guān)鍵字。不同的是JavaScript 的操作被簡化,只能通過一個 catch 語句塊來處理所有類型異常。而 Python 的做法和大多數(shù)高級語言一致,能多次、針對不同異常進(jìn)行分別處理,else 關(guān)鍵字算是一個特色功能。
  • 拋出方面,兩者只是關(guān)鍵字不同。

參考:

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容