为了账号安全,请及时绑定邮箱和手机立即绑定

预期类型“List[A]”(匹配泛型类型“List[_T]”),在正确类型的列表上得到

预期类型“List[A]”(匹配泛型类型“List[_T]”),在正确类型的列表上得到

芜湖不芜 2023-12-20 19:56:08
from typing import Listclass Base(object):    passclass A(Base):    passclass B(Base):    passa: List[A] = []b: List[B] = []c: List[Base] = a + b我正在Expected type 'List[A]' (matched generic type 'List[_T]'), got 'List[B]' instead继续b。我如何获得正确的警告,因为显然类型很好。
查看完整描述

1 回答

?
当年话下

TA贡献1890条经验 获得超9个赞

这些类型都不好。List不变的,意味着 aList[X]不能替代except和完全相等。同样,并不意味着且同样适用于。List[Y]XYA <: BaseList[A] <: List[Base]B

PEP 484:协变和逆变

[...]
默认情况下,泛型类型在所有类型变量中被认为是不变的,这意味着用类型注释的变量值List[Employee]必须与类型注释完全匹配——不允许类型参数的子类或超类(在本例中Employee) 。

虽然可以重新解释此操作的类型,但这并不明确。保守的类型检查器将拒绝该操作而不是猜测。


诸如此类的可变容器List是不变的,因为元素既可以插入(逆变)列表,也可以从(协变)列表中取出。如果不需要可变性,则使用不可变序列提供有效的类型注释:

from typing import Sequencea: Sequence[A] = []
b: Sequence[B] = []
c: Sequence[Base] = [*a, *b]

如果需要可变性,可以显式枚举List. 即使每个单独的列表实际上只包含一种类型,这也会预先扩大列表中预期的元素。

a: List[Union[A, B]] = []
b: List[Union[A, B]] = []
c: List[Union[A, B]] = a + b

先发制人地扩大操作数的类型可能是不可取的或不可能的。或者,也可以cast在使用现场进行安装。

a: List[A] = []
b: List[B] = []
c: List[Union[A, B]] = cast(List[Union[A, B]], a) + cast(List[Union[A, B]], a)

请注意,这cast实际上禁用了对强制转换值的类型检查。仅在已知正确的情况下使用它。


查看完整回答
反对 回复 2023-12-20
  • 1 回答
  • 0 关注
  • 105 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信