簡體   English   中英

mypy 應該從聯合選項中推斷類型嗎?

[英]Should mypy infer type from Union options?

在下面的代碼中, fn_int將僅使用int作為參數調用,但mypy抱怨我可能會向它傳遞一個str (反之亦然fn_str )。

我在這里缺少什么嗎? 在將 arguments 傳遞給fn_intfn_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 == 3x in range(5)之后,x 仍然可以是浮點數而不是整數。 (當然,標准字符串不會通過in range(4)檢查,標准 int 也不會通過== "str"檢查,但你可以有一個奇怪的子類。)

mypy 將對以下類型的表達式進行類型縮小:

  • isinstance(x, SomeClass)x縮小為SomeClass
  • issubclass(x, SomeClass)x縮小為Type[SomeClass]
  • type(x) is SomeClassx縮小為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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM