我有以下代码
from typing import Union
def add(a: Union[int, str], b: Union[int, str]) -> str:
return str(a) + str(b)
a: int = 1
b: int = 2
out = add(a, b) # nice
a: str = 'one'
b: str = 'two'
out = add(a, b) # nice
a: int = 1
b: str = 'two'
out = add(a, b) # I hope the static check can raise error here when a and b are different types
我希望
mypy
能够针对第三种情况提出错误。我该怎么办?
一种方法是
@overload
装饰器,它允许您定义可接受的参数的特定组合(将实现定义为更广泛的联合类型):
from typing import Union, overload
@overload
def add(a: int, b: int) -> str:
pass
@overload
def add(a: str, b: str) -> str:
pass
def add(a: Union[int, str], b: Union[int, str]) -> str:
return f"{a}{b}"
add(1, 2) # nice
add("one", "two") # nice
add(1, "two") # error: No overload variant of "add" matches argument types "int", "str"
另一个选项是
TypeVar
:
from typing import TypeVar
A = TypeVar("A", str, int)
def add(a: A, b: A) -> str:
return f"{a}{b}"
add(1, 2) # nice
add("one", "two") # nice
add(1, "two") # error: Value of type variable "A" of "add" cannot be "object"
这个错误有点神秘——它告诉我们两个参数的最接近的子类型(
A
需要对应)是object
,并且object
太宽泛而无法满足约束放在 A
的定义上。