问题描述
我正在尝试创建一个接受哺乳动物列表或动物列表作为参数的函数。
这是我的代码
from typing import Union,List
class Animals():
pass
class Mammels(Animals):
pass
def add_mammel(x : List[Union[Animals,Mammels]]):
x.append(Mammels())
l = [Mammels(),Mammels()]
add_mammel(l)
print(l)
此代码有效,但当我使用 mypy 检查此代码时,我得到以下内容
python -m mypy fourth.py
fourth.py:11: error: Argument 1 to "add_mammel" has incompatible type "List[Mammels]"; expected "List[Union[Animals,Mammels]]"
fourth.py:11: note: "List" is invariant -- see http://mypy.readthedocs.io/en/latest/common_issues.html#variance
fourth.py:11: note: Consider using "Sequence" instead,which is covariant
这个问题与“方差”有关,但我无法弄清楚它的真正含义。
解决方法
问题确实是变异。如果您不知道这意味着什么,请阅读this part of the mypy
docs。
当 mypy
分析您的代码时,它推断 l
的类型为 List[Mammels]
,这是比 List[Union[Animals,Mammels]]
更窄的类型,因为后者可以包含 {{ 1}} 对象。函数的注释表明列表包含 Animals
的能力很重要,因此它表示当您传入更受限制的类型时会出错。
正如 the documentation page linked in the error message 所建议的,一个简单的解决方法是显式注释 Animals
的类型,使其与函数建议的内容相匹配:
l
您无法从使用 l: List[Union[Animals,Mammels]] = [Mammels(),Mammels()]
而不是 Sequence
的替代建议中受益,因为您的函数正在改变传递给您的列表(而 List
是不可变类型).