我在 python 中遇到的一个问题是 List 类型是不变的 - 这意味着它只能保存特定类型的对象,否则你会得到类型错误(例如运行 mypy 时) - 但有时你需要在更通用的函数中使用集合,该函数可以接受基类(我们称之为 A)以及所有派生类的所有类型。一个明显的例子是这个
class A:
pass
class B(A):
pass
def print_list_a(my_list: List[A]) -> None:
print(my_list)
l1 = [A()]
l2 = [B()]
# print_list_a(l1)
# print_list_a(l2) # mypy error because l2 is not a list[A] and list is invariant
处理这个问题的最佳方法是什么?
我遇到了这个问题的两种解决方案。
一种是定义一个绑定到 A 的泛型类型,另一种是使用协变类型(如 Sequence),像这样
T = TypeVar('T', bound=A)
def print_list_t(my_list: List[T]) -> None:
print(my_list)
# This is fine!
print_list_t(l1)
print_list_t(l2)
# use covariant type Sequence in place of list
def print_sequence_a(my_sequence: Sequence[A]) -> None:
print(my_sequence)
# This is fine too because the sequence type is covariant
print_sequence_a(l1)
print_sequence_a(l2)
使用绑定类型的优点是类型
List
比Sequence更具体。但是,如果您很高兴您的函数可以接受任何类型的序列,那么使用这种协变类型会更容易。