當前位置:
首頁 > 知識 > 怎樣在python3.6中使用靜態類型檢查

怎樣在python3.6中使用靜態類型檢查

怎樣在python3.6中使用靜態類型檢查

打開今日頭條,查看更多精彩圖片

動態類型是python編程中經常被抱怨的地方。這意味著你在定義一個變數時沒有給定變數類型。變數的真實類型取決於變數被賦予的值。

怎樣在python3.6中使用靜態類型檢查

在這個例子中, president_name 是一個string類型,因為我們使用stirng創建它的。但是python解釋器直到運行了這行代碼才會知道這個變數是string類型。

跟python相比,java就是一個靜態類型的語言。在java中要創建一個同樣的變數,你必須明確指定變數的類型。

怎樣在python3.6中使用靜態類型檢查

因為java可以提前知道president_name只能存儲string類型,所以當你用這個變數存儲int類型 或者把這個變數傳遞給需要非字元串類型作為參數的函數時,java在編譯期就可發現並提示錯誤。

為什麼我要在乎類型

通常使用像python這樣的動態類型語言可以更快的寫出新的代碼,因為你不需要手動寫出每個變數的類型。但是 當你的代碼量開始變得巨大的時候,你將不可避免的碰到許多運行時錯誤,而這種類型的錯誤在靜態類型語言中通常可以避免。下面是在python中碰到的典型的bug

怎樣在python3.6中使用靜態類型檢查

我們所做的是讓用戶輸入他們的名字,並且列印出來。並且當用戶沒有輸入任何字元時,我們想要列印出"Hi, UserFirstName!"作為回退選項。

當你運行這個程序,並且輸入名字時,一切都很完美,但是當你不輸入任何文字時,程序就會崩潰。

怎樣在python3.6中使用靜態類型檢查

原因在於fallback_name不是一個字元串,它是一個字典。所以, 當使用fallback_name來調用get_frist_name時就會失敗,因為它沒有.split方法。

這是一個明顯並且容易修復的bug。但是, 是什麼使這個bug如此難於被發現呢?是因為只有你在輸入名字留空並且運行這個代碼才會發現這其中隱藏的錯誤。你可能測試了這個代碼無數次,但是你還是發現不了這個bug,因為你總是會輸入名字

靜態類型語言甚至在運行這行代碼之前就會阻止這個錯誤。靜態類型會告訴你,你不能把fallback_name傳遞到get_first_name中,因為它期望一個string類型的參數,但是你卻傳遞了一個Dict過去。你的編輯器甚至能在你輸入的時候就提醒你這個錯誤。

當這樣的錯誤出現在python中時,通常不是像這個例子這樣簡單。通常會隱藏在好幾層代碼之下。通常會因為傳入的數據跟以前期待的不一樣而被觸發。要解決這個問題,你通常必須重現用戶的輸入,然後來搞清楚哪裡出了問題。解決這樣的bug會浪費大量的時間,而這本該輕而易舉的避免的。

好消息是你可以在python中使用靜態類型,如果你想要的話。從python3.6開始,終於有了完備的語法來定義類型。

解決我們的bug

讓我使用類型定義來修改我們的程序,並且捕獲函數的輸入輸出。以下是更新版本

怎樣在python3.6中使用靜態類型檢查

在python3.6中,用以下形式來定義一個變數。

怎樣在python3.6中使用靜態類型檢查

當你使用一個初始化值來創建一個變數時,可以像下面這樣簡單。

怎樣在python3.6中使用靜態類型檢查

也可用以下方式來定義函數的輸入輸出。

怎樣在python3.6中使用靜態類型檢查

這非常簡單,這只是對python語法的一個小修改。現在我們定義好了類型,下面來看看我們運行代碼會發生什麼。

怎樣在python3.6中使用靜態類型檢查

甚至都不需要運行程序,python就可以知道在16行是不正確的。你可以修復這個bug而無需等到三個月後用戶輸入時才發現這個問題。

假如你使用像pycharm這樣的IDE,它會自動檢測類型,並且提示是你哪個地方在某些時候可能運行不成功。而無需等到你執行這段代碼。

怎樣在python3.6中使用靜態類型檢查

就是這麼簡單。

更多的python3.6類型語法示例

定義一個string或者int變數很簡單。但是當使用複雜數據類型,比如列表,或者字典時,會遇到一些頭痛的問題。幸運的是python3.6的新語法在處理這問題時不算太壞。至少不像那些事後加入類型語法的語言。

基本模式是從typing模塊中引入複雜類型的名字,並且在方括弧中傳入嵌套的類型。最常見的複雜類型就是Dict List 和 Tuple.可以像如下這樣使用。

怎樣在python3.6中使用靜態類型檢查

怎樣在python3.6中使用靜態類型檢查

Tuples有一點點特別,因為它允許你為每個成員分別定義類型。

怎樣在python3.6中使用靜態類型檢查

你也可以通過把複雜類型賦值給一個名字來創建一個類型別名

怎樣在python3.6中使用靜態類型檢查

有時候也許你的函數有足夠的彈性來處理一些不一樣的類型的數據。你可以使用Union類型來定義函數,使它可以接受多種不同類型。也可以給使用Any來接受任意類型。

python3.6同樣支持一些類似其他語言中的魔幻類型的東西。比如通用類型,或用戶自定義類型。

運行類型檢測工具

python3.6給你定義類型的語法。但是python自身沒有提供與之相關的工具。要想強製做類型檢測,你可以使用以下兩種方法。

1:下載開源的 MYPY 類型檢測工具並且作為你的單元測試或者開發流的一部分來運行。

2:使用pycharm這樣的內置了類型檢測的IDE。或者你有使用像ATOM這樣的編輯器,那麼可以下載相應的類型檢測插件。

我建議你兩者都用。pycharm和mypy使用不同的類型檢測機制。他們之間可以互補。你可以使用pycharm作為實時類型檢測,然後使用mypy作為單元測試的一部分來做最終檢測。

非常棒,我需要現在開始在python代碼中使用類型定義嗎

類型定義是python的一個非常新的語法,只在python3.6工作。假如你把加了類型定義的python代碼給其他開發者看,他們一定覺得你瘋了,並且無法相信這是合法的語法。而且mypy還在開發之中,並沒有發布一個穩定版本。

所以現在把類型定義引入到你的整個項目中還為時尚早。但是,如果你開始一個新項目,並且把python3.6作為最低要求版本,也許值得嘗試使用類型申明。這樣可以潛在的消除很多bug。

一個優雅的方式是你可混合類型定義和未類型定義的代碼。不需要孤注一擲,你可以直接在有價值的地方定義類型。而無需在所有的地方都定義類型。因為python在運行時並不會處理任何跟類型相關的事情,你不會因為類型定義而導致程序中斷。


英文原文:https://qiniumedia.freelycode.com/vcdn/1/優質文章長圖2/usestatictypecheck.pdf
譯者:Sailor

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

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


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

從Excel到Python,我到底經歷了什麼
不要在Python中編寫 lambda 表達式了

TAG:Python部落 |