的問題是,mypy推斷,你result
變量的類型是Dict[str, bool]
由於您第一次初始化後第2行
因此,當你嘗試後插入一個海峽,mypy(理所當然)笙歌。您有幾個修復代碼的選項,我將按照最不安全的順序列出。
選項1是宣佈你的字典,它的值是Any
型的 - 也就是你的值不會進行類型檢查都:我們需要註釋你的第二個
from typing import Any, Dict
def my_func(condition: bool) -> Dict[str, Any]:
result = {"success": False} # type: Dict[str, Any]
if condition:
result["success"] = True
else:
result["message"] = "error message"
return result
注請給mypy一個關於result
應該是什麼類型的暗示,以幫助其推理過程。
如果您使用Python 3.6+,可以註釋使用以下替代語法那條線,它使用可變註釋(這是新的像Python 3.6):
result: Dict[str, Any] = {"success": False}
選項2稍微更類型安全 - 使用Union
聲明你的值是strs或bools,但沒有別的。這不完全類型安全,但至少你仍然可以有一些檢查您的字典。
from typing import Any, Dict
def my_func(condition: bool) -> Dict[str, Union[str, bool]]:
result = {"success": False} # type: Dict[str, Union[str, bool]]
if condition:
result["success"] = True
else:
result["message"] = "error message"
return result
你也許會發現類型的註釋是有點長/惱人的類型,所以你可以使用類型別名可讀性(並選擇使用變量註釋語法),像這樣:
ResultJson = Dict[str, Union[str, bool]]
def my_func(condition: bool) -> ResultJson
result: ResultJson = {"success": False}
# ...snip...
選項3是最安全的,雖然它確實要求您使用實驗'TypedDict'類型,它允許您指定特定類型到字典中的不同字段。也就是說,使用這種類型需要您自擔風險 - AFAIK尚未添加到PEP 484中,這意味着其他類型檢查工具(如Pycharm的檢查器)沒有義務理解這一點。 Mypy本身只是最近增加了對TypedDict支持,因此可能仍然是越野車:
from typing import Optional
from mypy_extensions import TypedDict
ResultJson = TypedDict('ReturnJson', {'success': bool, 'message': Optional[str]})
def my_func(condition: bool) -> ResultJson:
result = {"success": False, "message": None} # type: ResultJson
if condition:
result["success"] = True
else:
result["message"] = "error message"
return result
一定要安裝mypy_extensions
包,如果你想使用這個選項。
感謝您的全面解答邁克爾!我認爲我爲mypy邏輯的某些概念而奮鬥,但你真的爲我清除了這個問題。旁註:當行數超過PEP8允許的79個字符時,您是否知道如何處理內聯類型提示? (我不能在這個項目中使用Python3.6,所以新的變量註釋語法不適用於我) –
@JanRozycki謹慎使用[type aliases](http://mypy.readthedocs.io/en/latest/ types_of_types.html#type-aliases)通常可以幫助緩解這個問題。當用許多參數輸入函數時,輸入你的函數[像這樣](http://mypy.readthedocs.io/en/latest/python2.html#multi-line-python-2-function- annotations)也是有幫助的。 – Michael0x2a