我将一个类型定义为由Literal
字符串组成的Union
Color = Literal[
"red",
"green",
"blue",
"yellow",
"orange",
"purple"
]
我有一个函数,它期望一个符合类型的字符串列表。
def f(colors: List[Color]):
...
我实例化了一个符合要求的字符串列表,并将其传递给函数
colors = ['blue', 'green']
f(colors)
Pylance 用警告标记了函数调用
Argument of type "list[str]" cannot be assigned to parameter "colors" of type "List[Color]" in function "f"
"list[str]" is incompatible with "List[Color]"
TypeVar "_T@list" is invariant
Type "str" cannot be assigned to type "Color"
"str" cannot be assigned to type "Literal['red']" Pylance(reportGeneralTypeIssues)
如果我明确地注释实例化的列表,警报就会消失
colors: List[Color] = ['blue', 'green']
这似乎是多余的。无论我是否注释,列表都与预期类型匹配。难道类型系统不应该认识到这一点吗?
事实上,我可以直接传递列表而不会有任何警告。
f(['blue', 'green']) # Pylance allows
Pylance也可以胜任这个任务
def f(seven: Literal[7]):
...
x = 7
f(x) # Pylance allows, doesn't require doing x: int = 7
所以它似乎只抱怨列表变量,而不是一般的隐式类型变量。
为什么我必须明确注释那些其值明确符合预期类型的列表变量呢?
def f(seven: Literal[7]); x = 7; f(x)
时不会出现相同的错误?x
是一个int
,恰好是7
,而f
需要的是Literal[7]
。难道x = 7
实际上被定义为Literal[7]
,这恰好是int
的子集,而类型系统无法轻松地知道['blue','green']
是否是Literal['red','green','blue', ...]
的子集吗? - Michael Moreno