2016-12-28 73 views
24

我注意到python 3.5和python 3.6增加了很多關於靜態類型檢查的功能,所以我嘗試了下面的代碼(在python 3.6中,穩定版本)。如何在python 3.6中使用類型提示?

from typing import List 

a: List[str] = [] 
a.append('a') 
a.append(1) 
print(a) 

讓我吃驚的是,蟒蛇沒有給我一個錯誤或警告,雖然1被附加到list它應該只包含字符串。 Pycharm檢測到類型錯誤,並給了我一個警告,但它並不明顯,並沒有顯示在輸出控制檯中,我有時會擔心我可能會錯過它。我想要以下效果:

  1. 如果很明顯我使用了錯誤的類型,如上所示,請拋出警告或錯誤。
  2. 如果編譯器無法可靠地檢查我使用的類型是對還是錯,請忽略它。

這可能嗎?也許mypy能做到這一點,但我更願意使用Python-3.6風格的類型檢查(如a: List[str]),而不是mypy使用的註釋風格(如# type List[str])。我很好奇,如果在本機python 3.6中有一個開關來實現上述兩點。

+0

mypy已經支持Python 3.6變量註釋。 – user2357112

+0

相關的,如果不是欺騙:[什麼是Python 3.5中的類型提示](http://stackoverflow.com/questions/32557920/what-are-type-hints-in-python-3-5/32558710#32558710)和[什麼是Python 3.6中的變量註釋?](http://stackoverflow.com/questions/39971929/what-are-variable-annotations-in-python-3-6?noredirect=1&lq=1) –

+0

爲了保持簡短:類型註釋並不意味着類型強制。該語言仍然是動態輸入的。 – jsbueno

回答

12

Is that possible? Maybe mypy could do it, but I'd prefer to use Python-3.6-style type checking (like a: List[str]) instead of the comment-style (like # type List[str]) used in mypy. And I'm curious if there's a switch in native python 3.6 to achieve the two points I said above.

Python無法爲您做到這一點;你可以使用mypy得到類型檢查(和PyCharms內置檢查器也應該這樣做)。除此之外,mypy不限制你只輸入評論# type List[str],因爲你在Python 3.6這麼做a: List[str]作品同樣可以使用變量註解。

隨着mypy的是,因爲釋放是新鮮的,你需要安裝typed_ast--fast-parser--python-version 3.6as documented in mypy's docs執行mypy。這可能會改變很快,但現在你需要他們得到它順利運行

更新:現在不需要--fast-parser--python-version 3.6

這樣做後,mypy檢測到a: List[str]上的第二個操作的不兼容性就好了。比方說,你的文件被稱爲tp_check.py with語句:

from typing import List 

a: List[str] = [] 
a.append('a') 
a.append(1) 
print(a) 

運行mypy與上述參數(你必須首先pip install -U typed_ast):

python -m mypy --fast-parser --python-version 3.6 tp_check.py 

捕獲錯誤:

tp_check.py:5: error: Argument 1 to "append" of "list" has incompatible type "int"; expected "str" 

如前所述在許多其他的答案類型提示與Python,mypyPyCharm s'類型檢查器是執行驗證的類型,不是Python本身。 Python目前不使用這些信息,它只是將其存儲爲元數據並在執行期間忽略它。

19

類型提示完全是指由Python運行時被忽略,而僅由第三方工具,如mypy和Pycharm的綜合檢查檢查。還有各種鮮爲人知的第三方工具,可以在編譯時或運行時使用類型註釋進行類型檢查,但大多數人使用mypy或Pycharm的集成檢查器AFAIK。事實上,我確實懷疑在可預見的將來,類型檢查將被整合到Python中 - 請參閱PEP 484(它引入類型註釋)和PEP 526(它引入了可變註釋)的「非目標」部分,以及Guido的評論here

我個人是會高興的類型檢查更加強烈與Python集成,但它似乎沒有Python社區在大是準備或願意爲這種改變。

mypy的最新版本應該明白於對Python 3.6變量註釋語法和註釋風格的語法。事實上,變量註釋基本上是Guido的想法(Guido目前是mypy團隊的一部分) - 基本上,對mypy和Python中的類型註釋的支持幾乎是同時開發的。

5

在Python中鍵入註釋並不意味着是類型強制。任何涉及運行時靜態類型依賴的東西都意味着變化如此基本,以至於繼續調用所產生的語言「Python」是沒有意義的。

請注意,Python的動態特性確實允許人們使用純Python代碼構建一個外部工具來執行運行時類型檢查。這會使程序運行(非常)緩慢,但也許它適用於某些測試類別。可以肯定的是 - Python語言的基本原理之一就是一切都是對象,並且您可以嘗試在運行時對對象執行任何操作。如果對象沒有符合嘗試操作的接口,它將在運行時失敗。

本質上靜態類型化的語言以不同的方式工作:在運行時嘗試運行對象時必須可用。在編譯步驟中,編譯器爲適當的對象在整個地方創建空格和插槽 - 並且在不符合類型的輸入中打破編譯。

Python的類型檢測允許任意數量的工具完全做到這一點:在實際運行應用程序(但獨立於編譯本身)之前的某個步驟中斷開併發出警告。但是,語言的本質不能被改變,實際上需要在運行時遵守這些對象 - 並且在編譯步驟本身的打字和打破將是人爲的。

雖然可以預計未來版本的Python可能會在Python運行時本身上合併編譯時類型檢查 - 很可能通過和可選的命令行切換。 (我不認爲它會默認 - 至少不會打破構建 - 也許它可以默認發出警告)

因此,Python不需要在運行時進行靜態類型檢查,因爲它會停止成爲Python。但至少有一種語言可以同時使用動態對象和靜態類型 - Cython語言,它實際上可以作爲Python超集。應該期望Cython將新的類型提示語法合併爲實際類型 - 很快宣佈。(目前它對可選的靜態類型變量使用不同的語法)