[英]Should mypy infer type from Union options?
在下面的代碼中, fn_int
將僅使用int
作為參數調用,但mypy
抱怨我可能會向它傳遞一個str
(反之亦然fn_str
)。
我在這里缺少什么嗎? 在將 arguments 傳遞給fn_int
和fn_str
之前,我應該/可以以某種方式縮小類型范圍嗎?
from typing import Union
def fn_int(arg: int) -> None:
print(arg)
def fn_str(arg: str) -> None:
print(arg)
def fn(arg: Union[str, int]) -> None:
if arg in range(4):
fn_int(arg)
elif arg == "str":
fn_str(arg)
else:
raise ValueError
> mypy mypy_test.py
mypy_test.py:15: error: Argument 1 to "fn_int" has incompatible type "Union[str, int]"; expected "int" [arg-type]
mypy_test.py:17: error: Argument 1 to "fn_str" has incompatible type "Union[str, int]"; expected "str" [arg-type]
您正在尋找的是type narrowing ,而 mypy 不會為==
或比較in
類型縮小。 畢竟,它們並不能真正保證類型。 作為一個相當常見的示例,在x == 3
或x in range(5)
之后,x 仍然可以是浮點數而不是整數。 (當然,標准字符串不會通過in range(4)
檢查,標准 int 也不會通過== "str"
檢查,但你可以有一個奇怪的子類。)
mypy 將對以下類型的表達式進行類型縮小:
isinstance(x, SomeClass)
將x
縮小為SomeClass
。issubclass(x, SomeClass)
將x
縮小為Type[SomeClass]
。type(x) is SomeClass
將x
縮小為SomeClass
。callable(x)
將x
縮小為可調用類型。 您還可以使用 typing.TypeGuard 編寫自己的類型保護, typing.TypeGuard
也能理解這些。
arg 是 str 或 int,但您永遠不會檢查它是哪種類型,因此請檢查if isinstance(arg, int)
。
然后 mypy 知道這個 function 只有在它是所需類型時才會被調用。
示例:
if isinstance(arg, int):
fn_int(arg)
elif isinstance(arg, str):
fn_str(arg)
else:
raise ValueError
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.