mypy 应该从联合选项中推断类型吗?
Should mypy infer type from Union options?
在下面的代码中,fn_int
将仅使用 int
作为参数调用,但 mypy
抱怨我可能将其传递给 str
(反之亦然fn_str
).
我在这里遗漏了什么吗?
Should/can 在将参数传递给 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]
arg 是 str 或 int,但你永远不会检查它是哪种类型,
因此检查 if isinstance(arg, int)
.
然后 mypy 知道这个函数只有在它是所需类型时才会被调用。
示例:
if isinstance(arg, int):
fn_int(arg)
elif isinstance(arg, str):
fn_str(arg)
else:
raise ValueError
您要查找的内容称为 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
编写你自己的类型保护,mypy 也会理解这些。
在下面的代码中,fn_int
将仅使用 int
作为参数调用,但 mypy
抱怨我可能将其传递给 str
(反之亦然fn_str
).
我在这里遗漏了什么吗?
Should/can 在将参数传递给 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]
arg 是 str 或 int,但你永远不会检查它是哪种类型,
因此检查 if isinstance(arg, int)
.
然后 mypy 知道这个函数只有在它是所需类型时才会被调用。
示例:
if isinstance(arg, int):
fn_int(arg)
elif isinstance(arg, str):
fn_str(arg)
else:
raise ValueError
您要查找的内容称为 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
编写你自己的类型保护,mypy 也会理解这些。