[英]Why does mypy infer the common base type instead of the union of all contained types?
[英]Python mypy unable to infer type from union return types
這是示例代碼
from typing import Dict, Union, Tuple
def select_range(data: Dict[str, Union[str, int]]) -> Tuple[int, int]:
if data['start'] and data['end']:
return data['start'], data['end']
return 1, 1
select_range({})
我的輸出:
mypy different_return.py
different_return.py:6: error: Incompatible return value type (got
"Tuple[Union[str, int], Union[str, int]]", expected "Tuple[int, int]")
即使字典值之一是int
,mypy 也無法推斷出來。
即使字典值之一是 int,mypy 也無法推斷出來。
Mypy 是正確的。 您的代碼有一個錯誤,而 mypy 正確地標記了它。 在您的代碼中不能保證data['start']
和data['end']
總是整數。
您的data
簽名是Dict[str, Union[str, int]]
,因此值的類型為Union[str, int]
。 Mypy必須假設傳入{'start': '2018-07-12', 'end': -42}
總是正確的,所以返回值必須是Tuple[Union[str, int], Union[str, int]]
。 您聲稱該函數返回Tuple[int, int]
與此沖突。
運行時實際發生什么並不重要。 這不是重點。 mypy 是一個靜態類型檢查器,旨在幫助保持您的運行時行為無錯誤。 這里重要的是,根據類型提示,可以為start
和end
傳入非整數值,因此類型檢查器無法保護您免受代碼中意外設置字符串值的未來錯誤的影響那兩個鍵。
如果您在字典中傳遞結構化數據,您將始終必須為此與 mypy 斗爭,因為字典確實是錯誤的結構。 您真的想在這里使用命名元組或數據類。
我在這里使用名稱FooBar
,但對於您的特定應用程序,我確信您傳遞的數據結構會有更好的名稱:
from typing import NamedTuple
class FooBar(NamedTuple):
start: int
end: int
# other fields, perhaps with defaults and Optionals
def select_range(data: FooBar) -> Tuple[int, int]:
if data.start and data.end:
return data.start, data.end
return 1, 1
代碼一切都很好。 你忘了得到你的函數參數:
from typing import Dict, Union, Tuple
def select_range(data: Dict[str, Union[str, int]]) -> Tuple[int, int]:
print (data)
if data['start'] and data['end']:
return data['start'], data['end']
return 1, 1
print (select_range({"start":[1,5], 'end':[2,6]}))
使用它來查找一些參數:
from typing import Dict, Union, Tuple
def select_range(data: Dict[str, Union[str, int]]) -> Tuple[int, int]:
# print (data)
if 'start' in data and 'end' in data:
return data['start'], data['end']
return 1, 1
print (select_range({"start":[5], 'end':[6]}))
#select_range({})
([5], [6]) 是工作的結果
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.