为何List[Dog]与List[Animal]不兼容?(Dog继承自Animal)
为什么
List[Animal] = List[Dog]报错,但直接赋值列表字面量却没问题? 这个问题的关键其实是mypy对泛型容器的不变性规则,以及它处理列表字面量时的特殊逻辑。我给你掰扯清楚:
1. 为啥arr2没报错?
当你写arr2: List[Animal] = [Dog(), Dog()]的时候,mypy会把右边的列表字面量直接当成List[Animal]来处理。因为你已经明确告诉它左边变量的类型是List[Animal],而列表里的每只狗都是Animal的子类,完全符合要求。
说白了,mypy这里会“顺着你的意思”,把这个新创建的列表的类型调整为List[Animal]——毕竟你之后要是往arr2里加一只猫,也是合法的,不会搞出类型混乱。
2. 为啥arr3会报错?
而arr1的类型是实打实的List[Dog],这意味着这个列表只能装狗。如果mypy允许你把arr1赋值给arr3(List[Animal]类型),就会埋下一个大坑:
- 你可以通过
arr3.append(Cat())往列表里塞一只猫 - 但
arr1本质还是List[Dog],等你之后从arr1里取元素想调用bark()的时候,就会直接报错(猫哪会叫啊)
为了防止这种运行时的崩溃,mypy把List这类泛型容器定为不变类型:List[Dog]和List[Animal]之间没有父子关系,不能互相赋值。
那怎么解决这个问题?
如果你确实需要把狗列表转换成动物列表,有两种靠谱的方式:
# 方式1:创建一个新列表,让mypy重新推断类型 arr3: List[Animal] = list(arr1) # 方式2:用类型断言(仅限你确定不会往列表里加其他动物的情况) from typing import cast arr3 = cast(List[Animal], arr1)
内容的提问来源于stack exchange,提问作者user3517175
相关产品推荐
相关产品推荐

