我有以下设置:
class A:
pass
class B(A):
pass
def add_element(lst: list[A], el: A) -> None:
lst.append(el)
lst: list[B] = [B()]
add_element(lst, B())
这会导致 mypy 出现错误:
t.py:11: error: Argument 1 to "add_element" has incompatible type "List[B]"; expected "List[A]"
t.py:11: note: "List" is invariant -- see https://mypy.readthedocs.io/en/stable/common_issues.html#variance
t.py:11: note: Consider using "Sequence" instead, which is covariant
如果我尝试这个:
def add_element(lst: Sequence[A], el: A) -> None:
lst.append(el)
我明白了
t.py:10: error: "Sequence[A]" has no attribute "append"
我可以想出强制其工作的方法,但是正确的方法是什么?
TypeVar
:
from typing import TypeVar
class A:
pass
class B(A):
pass
T = TypeVar('T', bound=A)
def add_element(lst: list[T], el: T) -> None:
lst.append(el)
lst: list[B] = [B()]
add_element(lst, B())
如果我们尝试编写使用 A 子类以外的其他内容的代码:
lst: list[int] = []
add_element(lst, 0)
然后mypy会抱怨:
typetest.py:13: error: Value of type variable "T" of "add_element" cannot be "int" [type-var]
Found 1 error in 1 file (checked 1 source file)