Python中的類型提示(下)

Python中的类型提示(下)

當你碰壁時

總而言之,要小心了,類型提示有時會產生奇怪的警告,這會讓人產生不好的感覺,就如這篇推特所總結的一樣:

Python中的类型提示(下)

記住,在你的手頭就有一些工具可以幫助你發現、理解和處理這些邊緣情況;

· 使用reveal_type來看推理的類型:

Python中的类型提示(下)

· 使用cast來強制一個給定的類型:

Python中的类型提示(下)

· 使用類型忽略標記來禁用行中的錯誤:

Python中的类型提示(下)

· 在論壇中提問;在python/typing的Gittter chat下提供一個可以暴露出問題的最簡潔的可復現版本。

工具

這裡有一份關於類型提示系統的不是很詳盡的工具列表。

類型檢查器

使用這些工具在你的庫或者應用中檢查類型是否正確:

1、mypy – Python(之前提到的類型linter工具)

2、pyre – Facebook –僅針對python3,但是比mypy的運行速度快。一個有趣的用例是使用這個工具來進行汙染/安全代碼的分析。參見Pieter Hooimeijer - Types, Deeper Static Analysis, and you.

3、pytype - Google.

類型標註生成器

當你想要對一個已存的代碼庫添加類型標註,使用這些來自動進行這個枯燥的部分:

1、mypy stubgen命令行

2、pyannotate – Dropbox –使用你的運行結果來生成類型信息。

3、monkeytype – Instagram。有趣的是,instagram實際上使用這個工具在自己的產品系統中運行:每一百萬次調用就觸發一次(這個工具使得代碼運行速度變慢了5倍,但一百萬次才觸發一次就不那麼明顯了)。

運行態的代碼鑑別器

使用這些工具來在運行時檢測輸入到你的函數或方法的參數的格式是否正確:

1、pydantic

2、enforce

3、pytypes

文檔增強-合併文檔字符串和類型提示

在這篇長文的第一部分,我們提到了以前人們就是將類型信息存儲在文檔字符串中。之所以這麼做的原因是類型數據也是你工作的一部分,你確實希望將庫的類型信息放入文檔中去。那麼問題來了,你沒有選擇使用文檔字符串作為類型信息的主要存儲系統,如何將這些信息保存在文檔字符串中呢?

這個答案取決於你用來生成文檔的工具。在這裡我將展示一種可選的方法,使用的工具是在python中最流行的工具和格式:Sphinx和HTML。

在類型提示和文檔字符串中都聲明類型信息最終一定會導致二者的衝突。你可以想象的到一個人同一時刻只能在一個地方更新信息。因此,讓我們從文檔字符串中刪除所有的類型數據,僅從類型提示中獲取。現在我們需要做的是在創建文檔是時從類型提示中獲取類型信息並加入到文檔中去。

在Sphinx中,你可以通過一個插件來實現這樣的操作。目前最流行的版本是agronholm/sphinx-autodoc-typehints。這個工具可以做兩件事:

· 首先,針對要記錄的每個函數或變量,它獲取類型提示信息;

· 然後,將這些信息用文檔字符串表示(這涉及到遞歸地展開所以嵌套的類型類,並用相應的字符串表示進行替換);

· 最後,將正確的參數附加進文檔字符串中去。

舉個例子,Any映射的類型是py:data:`~typing.Any`。對於組合類型來說會變得更加複雜,比如Mapping[str, bool]需要被翻譯成形如:class:`~typing.Mapping`\[:class:`str`, :class:`bool`]的字符串。正確的翻譯(例如類或者數據的名稱)對於intersphinx插件能夠正確的工作是至關重要的(一個能夠將類型直接鏈接到他們各自的python標準庫文檔的插件)。

為了使用這個工具,我們需要通過pip install sphinx-autodoc-type>=2.1.1來安裝,然後在conf.py文件中啟用:

Python中的类型提示(下)

這樣就可以了。這裡以RookieGameDevs/revived的文檔作為例子。比如給出如下的源代碼:

Python中的类型提示(下)

你可以得到這樣的輸出:

Python中的类型提示(下)

結論

這裡就是這篇長文的結尾了,你或許想問:類型提示是否值得使用,或者應該什麼時候使用。我認為類型提示和在一天的工作收尾時進行的單元測試在性質上是一樣的,只是代碼的表達方式不同。它們都提供了一種標準的(可複用的)方法來測試你代碼庫輸入輸出的類型。

正因如此,當值得編寫單元測試的時候,都應該使用類型提示。就算是以後需要維護的情況下,也只需要10行代碼就夠了。同樣,你還應該在你開始編寫單元測試的同時開始添加類型提示。我只在不需要單元測試的地方或者一次性的腳本上才不考慮添加類型提示。

記住,與單元測試類似,雖然它會使你的代碼庫中額外多出一些代碼。但是完成這項工作後,所有你添加的代碼都是用來自動檢查並確保其他部分的正確性的。它就像安全網一樣,確保當你在以後做出修改時程序可以繼續工作,所以為此付出額外的代價應該是值得的。

Python中的类型提示(下)
英文原文:https://www.bernat.tech/the-state-of-type-hints-in-python/
譯者:舞象加冠


分享到:


相關文章: